teiid SVN: r3364 - in trunk: api/src/main/java/org/teiid/language/visitor and 26 other directories.
by teiid-commits@lists.jboss.org
Author: shawkins
Date: 2011-08-05 14:33:39 -0400 (Fri, 05 Aug 2011)
New Revision: 3364
Modified:
trunk/api/src/main/java/org/teiid/language/Like.java
trunk/api/src/main/java/org/teiid/language/SQLConstants.java
trunk/api/src/main/java/org/teiid/language/visitor/SQLStringVisitor.java
trunk/api/src/main/java/org/teiid/translator/ExecutionFactory.java
trunk/build/kits/jboss-container/teiid-releasenotes.html
trunk/connectors/translator-jdbc/src/main/java/org/teiid/translator/jdbc/JDBCExecutionFactory.java
trunk/connectors/translator-jdbc/src/main/java/org/teiid/translator/jdbc/SQLConversionVisitor.java
trunk/connectors/translator-jdbc/src/main/java/org/teiid/translator/jdbc/h2/H2ExecutionFactory.java
trunk/connectors/translator-jdbc/src/main/java/org/teiid/translator/jdbc/mysql/MySQL5ExecutionFactory.java
trunk/connectors/translator-jdbc/src/main/java/org/teiid/translator/jdbc/oracle/OracleExecutionFactory.java
trunk/connectors/translator-jdbc/src/main/java/org/teiid/translator/jdbc/postgresql/PostgreSQLExecutionFactory.java
trunk/connectors/translator-jdbc/src/main/java/org/teiid/translator/jdbc/teiid/TeiidExecutionFactory.java
trunk/connectors/translator-jdbc/src/test/java/org/teiid/translator/jdbc/oracle/TestOracleTranslator.java
trunk/connectors/translator-jdbc/src/test/java/org/teiid/translator/jdbc/postgresql/TestPostgreSQLTranslator.java
trunk/documentation/developer-guide/src/main/docbook/en-US/content/translator-api.xml
trunk/documentation/reference/src/main/docbook/en-US/content/grammar.xml
trunk/documentation/reference/src/main/docbook/en-US/content/scalar_functions.xml
trunk/documentation/reference/src/main/docbook/en-US/content/sql_support.xml
trunk/engine/src/main/java/org/teiid/dqp/internal/datamgr/CapabilitiesConverter.java
trunk/engine/src/main/java/org/teiid/dqp/internal/datamgr/LanguageBridgeFactory.java
trunk/engine/src/main/java/org/teiid/query/eval/Evaluator.java
trunk/engine/src/main/java/org/teiid/query/metadata/TempCapabilitiesFinder.java
trunk/engine/src/main/java/org/teiid/query/optimizer/capabilities/SourceCapabilities.java
trunk/engine/src/main/java/org/teiid/query/optimizer/relational/rules/CriteriaCapabilityValidatorVisitor.java
trunk/engine/src/main/java/org/teiid/query/optimizer/relational/rules/NewCalculateCostUtil.java
trunk/engine/src/main/java/org/teiid/query/rewriter/QueryRewriter.java
trunk/engine/src/main/java/org/teiid/query/sql/lang/MatchCriteria.java
trunk/engine/src/main/java/org/teiid/query/sql/visitor/SQLStringVisitor.java
trunk/engine/src/main/java/org/teiid/query/tempdata/IndexInfo.java
trunk/engine/src/main/javacc/org/teiid/query/parser/SQLParser.jj
trunk/engine/src/test/java/org/teiid/query/parser/TestParser.java
trunk/engine/src/test/java/org/teiid/query/processor/TestTempTables.java
trunk/engine/src/test/java/org/teiid/query/processor/eval/TestExpressionEvaluator.java
trunk/engine/src/test/java/org/teiid/query/sql/visitor/TestSQLStringVisitor.java
Log:
TEIID-1694 TEIID-1602 adding support for like_regex and extract function parsing.
Modified: trunk/api/src/main/java/org/teiid/language/Like.java
===================================================================
--- trunk/api/src/main/java/org/teiid/language/Like.java 2011-08-04 17:51:11 UTC (rev 3363)
+++ trunk/api/src/main/java/org/teiid/language/Like.java 2011-08-05 18:33:39 UTC (rev 3364)
@@ -25,11 +25,21 @@
import org.teiid.language.visitor.LanguageObjectVisitor;
public class Like extends Condition implements Predicate {
+
+ public enum MatchMode {
+ LIKE,
+ SIMILAR,
+ /**
+ * The escape char is typically not used in regex mode.
+ */
+ REGEX
+ }
private Expression leftExpression;
private Expression rightExpression;
private Character escapeCharacter;
private boolean isNegated;
+ private MatchMode mode = MatchMode.LIKE;
public Like(Expression left, Expression right, Character escapeCharacter, boolean negated) {
leftExpression = left;
@@ -74,5 +84,13 @@
public void setNegated(boolean negated) {
this.isNegated = negated;
}
+
+ public MatchMode getMode() {
+ return mode;
+ }
+
+ public void setMode(MatchMode mode) {
+ this.mode = mode;
+ }
}
Modified: trunk/api/src/main/java/org/teiid/language/SQLConstants.java
===================================================================
--- trunk/api/src/main/java/org/teiid/language/SQLConstants.java 2011-08-04 17:51:11 UTC (rev 3363)
+++ trunk/api/src/main/java/org/teiid/language/SQLConstants.java 2011-08-05 18:33:39 UTC (rev 3364)
@@ -251,6 +251,7 @@
public static final String LEADING = "LEADING"; //$NON-NLS-1$
public static final String LEFT = "LEFT"; //$NON-NLS-1$
public static final String LIKE = "LIKE"; //$NON-NLS-1$
+ public static final String LIKE_REGEX = "LIKE_REGEX"; //$NON-NLS-1$
public static final String LOCAL = "LOCAL"; //$NON-NLS-1$
public static final String LOCALTIME = "LOCALTIME"; //$NON-NLS-1$
public static final String LOCALTIMESTAMP = "LOCALTIMESTAMP"; //$NON-NLS-1$
@@ -318,7 +319,7 @@
public static final String SESSION_USER = "SESSION_USER"; //$NON-NLS-1$
public static final String SET = "SET"; //$NON-NLS-1$
public static final String SHORT = "SHORT"; //$NON-NLS-1$
- public static final String SIILAR = "SIMILAR"; //$NON-NLS-1$
+ public static final String SIMILAR = "SIMILAR"; //$NON-NLS-1$
public static final String SMALLINT = "SMALLINT"; //$NON-NLS-1$
public static final String SOME = "SOME"; //$NON-NLS-1$
public static final String SPECIFIC = "SPECIFIC"; //$NON-NLS-1$
Modified: trunk/api/src/main/java/org/teiid/language/visitor/SQLStringVisitor.java
===================================================================
--- trunk/api/src/main/java/org/teiid/language/visitor/SQLStringVisitor.java 2011-08-04 17:51:11 UTC (rev 3363)
+++ trunk/api/src/main/java/org/teiid/language/visitor/SQLStringVisitor.java 2011-08-05 18:33:39 UTC (rev 3364)
@@ -611,9 +611,19 @@
buffer.append(Tokens.SPACE)
.append(NOT);
}
- buffer.append(Tokens.SPACE)
- .append(LIKE)
- .append(Tokens.SPACE);
+ buffer.append(Tokens.SPACE);
+ switch (obj.getMode()) {
+ case LIKE:
+ buffer.append(LIKE);
+ break;
+ case SIMILAR:
+ buffer.append(SIMILAR)
+ .append(Tokens.SPACE)
+ .append(TO);
+ case REGEX:
+ buffer.append(getLikeRegexString());
+ }
+ buffer.append(Tokens.SPACE);
append(obj.getRightExpression());
if (obj.getEscapeCharacter() != null) {
buffer.append(Tokens.SPACE)
@@ -623,10 +633,13 @@
.append(obj.getEscapeCharacter().toString())
.append(Tokens.QUOTE);
}
-
}
- public void visit(Limit obj) {
+ protected String getLikeRegexString() {
+ return LIKE_REGEX;
+ }
+
+ public void visit(Limit obj) {
buffer.append(LIMIT)
.append(Tokens.SPACE);
if (obj.getRowOffset() > 0) {
Modified: trunk/api/src/main/java/org/teiid/translator/ExecutionFactory.java
===================================================================
--- trunk/api/src/main/java/org/teiid/translator/ExecutionFactory.java 2011-08-04 17:51:11 UTC (rev 3363)
+++ trunk/api/src/main/java/org/teiid/translator/ExecutionFactory.java 2011-08-05 18:33:39 UTC (rev 3364)
@@ -894,4 +894,20 @@
return false;
}
+ /**
+ * @return true if the SIMILAR TO predicate is supported
+ * @since 7.5
+ */
+ public boolean supportsSimilarTo() {
+ return false;
+ }
+
+ /**
+ * @return true if the LIKE_REGEX predicate is supported
+ * @since 7.4
+ */
+ public boolean supportsLikeRegex() {
+ return false;
+ }
+
}
Modified: trunk/build/kits/jboss-container/teiid-releasenotes.html
===================================================================
--- trunk/build/kits/jboss-container/teiid-releasenotes.html 2011-08-04 17:51:11 UTC (rev 3363)
+++ trunk/build/kits/jboss-container/teiid-releasenotes.html 2011-08-05 18:33:39 UTC (rev 3364)
@@ -27,6 +27,7 @@
<H2><A NAME="Highlights"></A>Highlights</H2>
<UL>
<LI><B>Window function support</B> - Teiid and pushdown support was added for SQL 2003 OLAP window functions. The analytical ranking functions RANK, DENSE_RANK, and ROW_NUMBER were also added. See the reference for more.
+ <LI><B>Additional ANSI support</B> - Teiid and pushdown support was added for SUBSTRING using FROM/FOR syntax, TRIM, EXTRACT, SIMILAR TO, and LIKE_REGEX. See the reference for more.
<LI><B>Subquery optimization control</B> - added the DJ hint to indicate that a subquery should be the independent side of a dependent join.
<LI><B>MAKEIND Hint</B> - The MAKEIND hint can be used to indicate that the other side of the join should be made dependent.
<LI><B>ODBC SSL</B> - added support for SSL encrypted ODBC connections.
@@ -53,7 +54,7 @@
<h4>from 7.4</h4>
<ul>
- <li>OFFSET was added as a keyword.
+ <li>OFFSET and LIKE_REGEX were added as reserved words.
<li>ColumnReference.getName will always return just the element name. Previously it inconsistently returned the qualified and unqualified form depending upon where the ColumnReference appeared.
<li>As per JDBC4, ResultSetMetadata.getColumnName will return the unaliased column name if available rather than return the alias. Set useJDBC4ColumnNameAndLabelSemantics to false to use the alias name as the column name.
</ul>
Modified: trunk/connectors/translator-jdbc/src/main/java/org/teiid/translator/jdbc/JDBCExecutionFactory.java
===================================================================
--- trunk/connectors/translator-jdbc/src/main/java/org/teiid/translator/jdbc/JDBCExecutionFactory.java 2011-08-04 17:51:11 UTC (rev 3363)
+++ trunk/connectors/translator-jdbc/src/main/java/org/teiid/translator/jdbc/JDBCExecutionFactory.java 2011-08-05 18:33:39 UTC (rev 3364)
@@ -57,6 +57,7 @@
import org.teiid.language.Limit;
import org.teiid.language.Literal;
import org.teiid.language.QueryExpression;
+import org.teiid.language.SQLConstants;
import org.teiid.language.SetQuery;
import org.teiid.language.Argument.Direction;
import org.teiid.language.SetQuery.Operation;
@@ -1147,5 +1148,9 @@
}
return nameParts;
}
+
+ public String getLikeRegexString() {
+ return SQLConstants.Reserved.LIKE_REGEX;
+ }
}
Modified: trunk/connectors/translator-jdbc/src/main/java/org/teiid/translator/jdbc/SQLConversionVisitor.java
===================================================================
--- trunk/connectors/translator-jdbc/src/main/java/org/teiid/translator/jdbc/SQLConversionVisitor.java 2011-08-04 17:51:11 UTC (rev 3363)
+++ trunk/connectors/translator-jdbc/src/main/java/org/teiid/translator/jdbc/SQLConversionVisitor.java 2011-08-05 18:33:39 UTC (rev 3364)
@@ -350,4 +350,9 @@
return executionFactory.useSelectLimit();
}
+ @Override
+ protected String getLikeRegexString() {
+ return executionFactory.getLikeRegexString();
+ }
+
}
Modified: trunk/connectors/translator-jdbc/src/main/java/org/teiid/translator/jdbc/h2/H2ExecutionFactory.java
===================================================================
--- trunk/connectors/translator-jdbc/src/main/java/org/teiid/translator/jdbc/h2/H2ExecutionFactory.java 2011-08-04 17:51:11 UTC (rev 3363)
+++ trunk/connectors/translator-jdbc/src/main/java/org/teiid/translator/jdbc/h2/H2ExecutionFactory.java 2011-08-05 18:33:39 UTC (rev 3364)
@@ -200,4 +200,14 @@
public boolean supportsAggregatesEnhancedNumeric() {
return true;
}
+
+ @Override
+ public boolean supportsLikeRegex() {
+ return true;
+ }
+
+ @Override
+ public String getLikeRegexString() {
+ return "REGEXP"; //$NON-NLS-1$
+ }
}
Modified: trunk/connectors/translator-jdbc/src/main/java/org/teiid/translator/jdbc/mysql/MySQL5ExecutionFactory.java
===================================================================
--- trunk/connectors/translator-jdbc/src/main/java/org/teiid/translator/jdbc/mysql/MySQL5ExecutionFactory.java 2011-08-04 17:51:11 UTC (rev 3363)
+++ trunk/connectors/translator-jdbc/src/main/java/org/teiid/translator/jdbc/mysql/MySQL5ExecutionFactory.java 2011-08-05 18:33:39 UTC (rev 3364)
@@ -27,9 +27,9 @@
import java.util.List;
import org.teiid.language.Function;
+import org.teiid.translator.SourceSystemFunctions;
import org.teiid.translator.Translator;
import org.teiid.translator.TranslatorException;
-import org.teiid.translator.SourceSystemFunctions;
import org.teiid.translator.jdbc.FunctionModifier;
@Translator(name="mysql5", description="A translator for open source MySQL5 Database")
@@ -65,5 +65,15 @@
public boolean supportsAggregatesEnhancedNumeric() {
return true;
}
+
+ @Override
+ public boolean supportsLikeRegex() {
+ return true;
+ }
+
+ @Override
+ public String getLikeRegexString() {
+ return "REGEXP"; //$NON-NLS-1$
+ }
}
Modified: trunk/connectors/translator-jdbc/src/main/java/org/teiid/translator/jdbc/oracle/OracleExecutionFactory.java
===================================================================
--- trunk/connectors/translator-jdbc/src/main/java/org/teiid/translator/jdbc/oracle/OracleExecutionFactory.java 2011-08-04 17:51:11 UTC (rev 3363)
+++ trunk/connectors/translator-jdbc/src/main/java/org/teiid/translator/jdbc/oracle/OracleExecutionFactory.java 2011-08-05 18:33:39 UTC (rev 3364)
@@ -538,4 +538,14 @@
return true;
}
+ @Override
+ public boolean supportsLikeRegex() {
+ return true;
+ }
+
+ @Override
+ public String getLikeRegexString() {
+ return "REGEXP_LIKE"; //$NON-NLS-1$
+ }
+
}
Modified: trunk/connectors/translator-jdbc/src/main/java/org/teiid/translator/jdbc/postgresql/PostgreSQLExecutionFactory.java
===================================================================
--- trunk/connectors/translator-jdbc/src/main/java/org/teiid/translator/jdbc/postgresql/PostgreSQLExecutionFactory.java 2011-08-04 17:51:11 UTC (rev 3363)
+++ trunk/connectors/translator-jdbc/src/main/java/org/teiid/translator/jdbc/postgresql/PostgreSQLExecutionFactory.java 2011-08-05 18:33:39 UTC (rev 3364)
@@ -33,8 +33,10 @@
import org.teiid.language.Expression;
import org.teiid.language.Function;
import org.teiid.language.LanguageObject;
+import org.teiid.language.Like;
import org.teiid.language.Limit;
import org.teiid.language.Literal;
+import org.teiid.language.Like.MatchMode;
import org.teiid.language.SQLConstants.NonReserved;
import org.teiid.translator.ExecutionContext;
import org.teiid.translator.SourceSystemFunctions;
@@ -230,6 +232,11 @@
agg.setName("bool_or"); //$NON-NLS-1$
}
}
+ } else if (obj instanceof Like) {
+ Like like = (Like)obj;
+ if (like.getMode() == MatchMode.REGEX) {
+ return Arrays.asList(like.getLeftExpression(), like.isNegated()?" !~ ":" ~ ", like.getRightExpression()); //$NON-NLS-1$ //$NON-NLS-2$
+ }
}
return super.translate(obj, context);
}
@@ -498,4 +505,14 @@
return getDatabaseVersion().compareTo(EIGHT_4) >= 0;
}
+ @Override
+ public boolean supportsSimilarTo() {
+ return true;
+ }
+
+ @Override
+ public boolean supportsLikeRegex() {
+ return true;
+ }
+
}
Modified: trunk/connectors/translator-jdbc/src/main/java/org/teiid/translator/jdbc/teiid/TeiidExecutionFactory.java
===================================================================
--- trunk/connectors/translator-jdbc/src/main/java/org/teiid/translator/jdbc/teiid/TeiidExecutionFactory.java 2011-08-04 17:51:11 UTC (rev 3363)
+++ trunk/connectors/translator-jdbc/src/main/java/org/teiid/translator/jdbc/teiid/TeiidExecutionFactory.java 2011-08-05 18:33:39 UTC (rev 3364)
@@ -221,4 +221,14 @@
public boolean supportsArrayAgg() {
return getDatabaseVersion().compareTo(SEVEN_5) >= 0;
}
+
+ @Override
+ public boolean supportsLikeRegex() {
+ return getDatabaseVersion().compareTo(SEVEN_5) >= 0;
+ }
+
+ @Override
+ public boolean supportsSimilarTo() {
+ return getDatabaseVersion().compareTo(SEVEN_5) >= 0;
+ }
}
Modified: trunk/connectors/translator-jdbc/src/test/java/org/teiid/translator/jdbc/oracle/TestOracleTranslator.java
===================================================================
--- trunk/connectors/translator-jdbc/src/test/java/org/teiid/translator/jdbc/oracle/TestOracleTranslator.java 2011-08-04 17:51:11 UTC (rev 3363)
+++ trunk/connectors/translator-jdbc/src/test/java/org/teiid/translator/jdbc/oracle/TestOracleTranslator.java 2011-08-05 18:33:39 UTC (rev 3364)
@@ -22,7 +22,7 @@
package org.teiid.translator.jdbc.oracle;
-import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.*;
import java.util.List;
@@ -43,8 +43,8 @@
import org.teiid.query.metadata.QueryMetadataInterface;
import org.teiid.query.metadata.TransformationMetadata;
import org.teiid.query.unittest.RealMetadataFactory;
+import org.teiid.translator.ExecutionContext;
import org.teiid.translator.TranslatorException;
-import org.teiid.translator.ExecutionContext;
import org.teiid.translator.jdbc.TranslatedCommand;
import org.teiid.translator.jdbc.TranslationHelper;
@@ -780,5 +780,14 @@
String expected = "SELECT (1 / tan(SmallA.DoubleNum)) FROM SmallA"; //$NON-NLS-1$
helpTestVisitor(RealMetadataFactory.exampleBQTCached(), sql, EMPTY_CONTEXT, null, expected);
}
+
+ @Test public void testLikeRegex() throws Exception {
+ String input = "SELECT intkey FROM BQT1.SMALLA where stringkey like_regex 'ab.*c+' and stringkey not like_regex 'ab{3,5}c'"; //$NON-NLS-1$
+ String output = "SELECT SmallA.IntKey FROM SmallA WHERE SmallA.StringKey REGEXP_LIKE 'ab.*c+' AND SmallA.StringKey NOT REGEXP_LIKE 'ab{3,5}c'"; //$NON-NLS-1$
+ TranslationHelper.helpTestVisitor(TranslationHelper.BQT_VDB,
+ input, output,
+ TRANSLATOR);
+ }
+
}
Modified: trunk/connectors/translator-jdbc/src/test/java/org/teiid/translator/jdbc/postgresql/TestPostgreSQLTranslator.java
===================================================================
--- trunk/connectors/translator-jdbc/src/test/java/org/teiid/translator/jdbc/postgresql/TestPostgreSQLTranslator.java 2011-08-04 17:51:11 UTC (rev 3363)
+++ trunk/connectors/translator-jdbc/src/test/java/org/teiid/translator/jdbc/postgresql/TestPostgreSQLTranslator.java 2011-08-05 18:33:39 UTC (rev 3364)
@@ -544,5 +544,14 @@
input, output,
TRANSLATOR);
}
+
+ @Test public void testLikeRegex() throws Exception {
+ String input = "SELECT intkey FROM BQT1.SMALLA where stringkey like_regex 'ab.*c+' and stringkey not like_regex 'ab{3,5}c'"; //$NON-NLS-1$
+ String output = "SELECT SmallA.IntKey FROM SmallA WHERE SmallA.StringKey ~ 'ab.*c+' AND SmallA.StringKey !~ 'ab{3,5}c'"; //$NON-NLS-1$
+
+ TranslationHelper.helpTestVisitor(TranslationHelper.BQT_VDB,
+ input, output,
+ TRANSLATOR);
+ }
}
Modified: trunk/documentation/developer-guide/src/main/docbook/en-US/content/translator-api.xml
===================================================================
--- trunk/documentation/developer-guide/src/main/docbook/en-US/content/translator-api.xml 2011-08-04 17:51:11 UTC (rev 3363)
+++ trunk/documentation/developer-guide/src/main/docbook/en-US/content/translator-api.xml 2011-08-05 18:33:39 UTC (rev 3364)
@@ -423,7 +423,7 @@
<listitem><para><code>SubqueryIn</code> – represents an IN criteria that uses a subquery to produce the value set</para></listitem>
<listitem><para><code>IsNull</code> – represents an IS NULL criteria</para></listitem>
<listitem><para><code>Exists</code> – represents an EXISTS criteria that determines whether a subquery will return any values</para></listitem>
- <listitem><para><code>Like</code> – represents a LIKE criteria that compares string values</para></listitem>
+ <listitem><para><code>Like</code> – represents a LIKE/SIMILAR TO/LIKE_REGEX criteria that compares string values</para></listitem>
</itemizedlist>
</section>
@@ -879,6 +879,28 @@
</row>
<row>
<entry>
+ <para>SimilarTo</para>
+ </entry>
+ <entry>
+ <para/>
+ </entry>
+ <entry>
+ <para>Translator can support SIMILAR TO criteria.</para>
+ </entry>
+ </row>
+ <row>
+ <entry>
+ <para>LikeRegexCriteria</para>
+ </entry>
+ <entry>
+ <para/>
+ </entry>
+ <entry>
+ <para>Translator can support LIKE_REGEX criteria.</para>
+ </entry>
+ </row>
+ <row>
+ <entry>
<para>InCriteria</para>
</entry>
<entry>
Modified: trunk/documentation/reference/src/main/docbook/en-US/content/grammar.xml
===================================================================
--- trunk/documentation/reference/src/main/docbook/en-US/content/grammar.xml 2011-08-04 17:51:11 UTC (rev 3363)
+++ trunk/documentation/reference/src/main/docbook/en-US/content/grammar.xml 2011-08-05 18:33:39 UTC (rev 3364)
@@ -170,6 +170,7 @@
| <LARGE: "large">
| <LEADING: "leading">
| <LIKE: "like">
+| <LIKE_REGEX: "like_regex">
| <LIMIT: "limit">
| <LOCAL: "local">
| <LOOP: "loop">
@@ -717,32 +718,36 @@
<row>
<entry align="right" valign="top"><para><anchor id="prod71" xreflabel="booleanPrimary"/>booleanPrimary</para></entry>
<entry align="left" valign="top"><para>::=
-( <link linkend="prod41">translateCriteria</link> | ( <link linkend="prod91">commonValueExpression</link> ( ( <link linkend="prod92">betweenCrit</link> | <link linkend="prod93">matchCrit</link> | <link linkend="prod94">setCrit</link> | <link linkend="prod95">isNullCrit</link> | <link linkend="prod96">subqueryCompareCriteria</link> | <link linkend="prod97">compareCrit</link> ) )? ) | <link linkend="prod98">existsCriteria</link> | <link linkend="prod37">hasCriteria</link> )</para></entry></row>
+( <link linkend="prod41">translateCriteria</link> | ( <link linkend="prod91">commonValueExpression</link> ( ( <link linkend="prod92">betweenCrit</link> | <link linkend="prod93">matchCrit</link> | <link linkend="prod94">regexMatchCrit</link> | <link linkend="prod95">setCrit</link> | <link linkend="prod96">isNullCrit</link> | <link linkend="prod97">subqueryCompareCriteria</link> | <link linkend="prod98">compareCrit</link> ) )? ) | <link linkend="prod99">existsCriteria</link> | <link linkend="prod37">hasCriteria</link> )</para></entry></row>
<row>
-<entry align="right" valign="top"><para><anchor id="prod99" xreflabel="operator"/>operator</para></entry>
+<entry align="right" valign="top"><para><anchor id="prod100" xreflabel="operator"/>operator</para></entry>
<entry align="left" valign="top"><para>::=
( <EQ> | <NE> | <NE2> | <LT> | <LE> | <GT> | <GE> )</para></entry></row>
<row>
-<entry align="right" valign="top"><para><anchor id="prod97" xreflabel="compareCrit"/>compareCrit</para></entry>
+<entry align="right" valign="top"><para><anchor id="prod98" xreflabel="compareCrit"/>compareCrit</para></entry>
<entry align="left" valign="top"><para>::=
-<link linkend="prod99">operator</link> <link linkend="prod91">commonValueExpression</link></para></entry></row>
+<link linkend="prod100">operator</link> <link linkend="prod91">commonValueExpression</link></para></entry></row>
<row>
-<entry align="right" valign="top"><para><anchor id="prod100" xreflabel="subquery"/>subquery</para></entry>
+<entry align="right" valign="top"><para><anchor id="prod101" xreflabel="subquery"/>subquery</para></entry>
<entry align="left" valign="top"><para>::=
<LPAREN> ( <link linkend="prod13">queryExpression</link> | ( <link linkend="prod15">storedProcedure</link> ) ) <RPAREN></para></entry></row>
<row>
-<entry align="right" valign="top"><para><anchor id="prod101" xreflabel="subqueryAndHint"/>subqueryAndHint</para></entry>
+<entry align="right" valign="top"><para><anchor id="prod102" xreflabel="subqueryAndHint"/>subqueryAndHint</para></entry>
<entry align="left" valign="top"><para>::=
-<link linkend="prod100">subquery</link></para></entry></row>
+<link linkend="prod101">subquery</link></para></entry></row>
<row>
-<entry align="right" valign="top"><para><anchor id="prod96" xreflabel="subqueryCompareCriteria"/>subqueryCompareCriteria</para></entry>
+<entry align="right" valign="top"><para><anchor id="prod97" xreflabel="subqueryCompareCriteria"/>subqueryCompareCriteria</para></entry>
<entry align="left" valign="top"><para>::=
-<link linkend="prod99">operator</link> ( <ANY> | <SOME> | <ALL> ) <link linkend="prod100">subquery</link></para></entry></row>
+<link linkend="prod100">operator</link> ( <ANY> | <SOME> | <ALL> ) <link linkend="prod101">subquery</link></para></entry></row>
<row>
<entry align="right" valign="top"><para><anchor id="prod93" xreflabel="matchCrit"/>matchCrit</para></entry>
<entry align="left" valign="top"><para>::=
-( <NOT> )? <LIKE> <link linkend="prod91">commonValueExpression</link> ( <ESCAPE> <link linkend="prod69">charVal</link> | ( <LBRACE> <ESCAPE> <link linkend="prod69">charVal</link> <RBRACE> ) )?</para></entry></row>
+( <NOT> )? ( <LIKE> | ( <SIMILAR> <TO> ) ) <link linkend="prod91">commonValueExpression</link> ( <ESCAPE> <link linkend="prod69">charVal</link> | ( <LBRACE> <ESCAPE> <link linkend="prod69">charVal</link> <RBRACE> ) )?</para></entry></row>
<row>
+<entry align="right" valign="top"><para><anchor id="prod94" xreflabel="regexMatchCrit"/>regexMatchCrit</para></entry>
+<entry align="left" valign="top"><para>::=
+( <NOT> )? <LIKE_REGEX> <link linkend="prod91">commonValueExpression</link></para></entry></row>
+<row>
<entry align="right" valign="top"><para><anchor id="prod69" xreflabel="charVal"/>charVal</para></entry>
<entry align="left" valign="top"><para>::=
<link linkend="prod1">stringVal</link></para></entry></row>
@@ -751,17 +756,17 @@
<entry align="left" valign="top"><para>::=
( <NOT> )? <BETWEEN> <link linkend="prod91">commonValueExpression</link> <AND> <link linkend="prod91">commonValueExpression</link></para></entry></row>
<row>
-<entry align="right" valign="top"><para><anchor id="prod95" xreflabel="isNullCrit"/>isNullCrit</para></entry>
+<entry align="right" valign="top"><para><anchor id="prod96" xreflabel="isNullCrit"/>isNullCrit</para></entry>
<entry align="left" valign="top"><para>::=
<IS> ( <NOT> )? <NULL></para></entry></row>
<row>
-<entry align="right" valign="top"><para><anchor id="prod94" xreflabel="setCrit"/>setCrit</para></entry>
+<entry align="right" valign="top"><para><anchor id="prod95" xreflabel="setCrit"/>setCrit</para></entry>
<entry align="left" valign="top"><para>::=
-( <NOT> )? <IN> ( ( <link linkend="prod101">subqueryAndHint</link> ) | ( <LPAREN> <link linkend="prod91">commonValueExpression</link> ( <COMMA> <link linkend="prod91">commonValueExpression</link> )* <RPAREN> ) )</para></entry></row>
+( <NOT> )? <IN> ( ( <link linkend="prod102">subqueryAndHint</link> ) | ( <LPAREN> <link linkend="prod91">commonValueExpression</link> ( <COMMA> <link linkend="prod91">commonValueExpression</link> )* <RPAREN> ) )</para></entry></row>
<row>
-<entry align="right" valign="top"><para><anchor id="prod98" xreflabel="existsCriteria"/>existsCriteria</para></entry>
+<entry align="right" valign="top"><para><anchor id="prod99" xreflabel="existsCriteria"/>existsCriteria</para></entry>
<entry align="left" valign="top"><para>::=
-<EXISTS> <link linkend="prod101">subqueryAndHint</link></para></entry></row>
+<EXISTS> <link linkend="prod102">subqueryAndHint</link></para></entry></row>
<row>
<entry align="right" valign="top"><para><anchor id="prod60" xreflabel="groupBy"/>groupBy</para></entry>
<entry align="left" valign="top"><para>::=
@@ -773,27 +778,27 @@
<row>
<entry align="right" valign="top"><para><anchor id="prod53" xreflabel="orderby"/>orderby</para></entry>
<entry align="left" valign="top"><para>::=
-<ORDER> <BY> <link linkend="prod102">sortSpecification</link> ( <COMMA> <link linkend="prod102">sortSpecification</link> )*</para></entry></row>
+<ORDER> <BY> <link linkend="prod103">sortSpecification</link> ( <COMMA> <link linkend="prod103">sortSpecification</link> )*</para></entry></row>
<row>
-<entry align="right" valign="top"><para><anchor id="prod102" xreflabel="sortSpecification"/>sortSpecification</para></entry>
+<entry align="right" valign="top"><para><anchor id="prod103" xreflabel="sortSpecification"/>sortSpecification</para></entry>
<entry align="left" valign="top"><para>::=
-<link linkend="prod103">sortKey</link> ( <ASC> | <DESC> )? ( <link linkend="prod11">nonReserved</link> <link linkend="prod11">nonReserved</link> )?</para></entry></row>
+<link linkend="prod104">sortKey</link> ( <ASC> | <DESC> )? ( <link linkend="prod11">nonReserved</link> <link linkend="prod11">nonReserved</link> )?</para></entry></row>
<row>
-<entry align="right" valign="top"><para><anchor id="prod103" xreflabel="sortKey"/>sortKey</para></entry>
+<entry align="right" valign="top"><para><anchor id="prod104" xreflabel="sortKey"/>sortKey</para></entry>
<entry align="left" valign="top"><para>::=
<link linkend="prod24">expression</link></para></entry></row>
<row>
-<entry align="right" valign="top"><para><anchor id="prod104" xreflabel="intParam"/>intParam</para></entry>
+<entry align="right" valign="top"><para><anchor id="prod105" xreflabel="intParam"/>intParam</para></entry>
<entry align="left" valign="top"><para>::=
( <link linkend="prod84">intVal</link> | <QMARK> )</para></entry></row>
<row>
<entry align="right" valign="top"><para><anchor id="prod54" xreflabel="limit"/>limit</para></entry>
<entry align="left" valign="top"><para>::=
-( ( <LIMIT> <link linkend="prod104">intParam</link> ( <COMMA> <link linkend="prod104">intParam</link> )? ) | ( <OFFSET> <link linkend="prod104">intParam</link> ( <ROW> | <ROWS> ) ( <link linkend="prod105">fetchLimit</link> )? ) | ( <link linkend="prod105">fetchLimit</link> ) )</para></entry></row>
+( ( <LIMIT> <link linkend="prod105">intParam</link> ( <COMMA> <link linkend="prod105">intParam</link> )? ) | ( <OFFSET> <link linkend="prod105">intParam</link> ( <ROW> | <ROWS> ) ( <link linkend="prod106">fetchLimit</link> )? ) | ( <link linkend="prod106">fetchLimit</link> ) )</para></entry></row>
<row>
-<entry align="right" valign="top"><para><anchor id="prod105" xreflabel="fetchLimit"/>fetchLimit</para></entry>
+<entry align="right" valign="top"><para><anchor id="prod106" xreflabel="fetchLimit"/>fetchLimit</para></entry>
<entry align="left" valign="top"><para>::=
-<FETCH> <link linkend="prod11">nonReserved</link> ( <link linkend="prod104">intParam</link> )? ( <ROW> | <ROWS> ) <ONLY></para></entry></row>
+<FETCH> <link linkend="prod11">nonReserved</link> ( <link linkend="prod105">intParam</link> )? ( <ROW> | <ROWS> ) <ONLY></para></entry></row>
<row>
<entry align="right" valign="top"><para><anchor id="prod45" xreflabel="option"/>option</para></entry>
<entry align="left" valign="top"><para>::=
@@ -805,73 +810,73 @@
<row>
<entry align="right" valign="top"><para><anchor id="prod91" xreflabel="commonValueExpression"/>commonValueExpression</para></entry>
<entry align="left" valign="top"><para>::=
-( <link linkend="prod106">plusExpression</link> ( <CONCAT_OP> <link linkend="prod106">plusExpression</link> )* )</para></entry></row>
+( <link linkend="prod107">plusExpression</link> ( <CONCAT_OP> <link linkend="prod107">plusExpression</link> )* )</para></entry></row>
<row>
-<entry align="right" valign="top"><para><anchor id="prod106" xreflabel="plusExpression"/>plusExpression</para></entry>
+<entry align="right" valign="top"><para><anchor id="prod107" xreflabel="plusExpression"/>plusExpression</para></entry>
<entry align="left" valign="top"><para>::=
-( <link linkend="prod107">timesExpression</link> ( <link linkend="prod108">plusOperator</link> <link linkend="prod107">timesExpression</link> )* )</para></entry></row>
+( <link linkend="prod108">timesExpression</link> ( <link linkend="prod109">plusOperator</link> <link linkend="prod108">timesExpression</link> )* )</para></entry></row>
<row>
-<entry align="right" valign="top"><para><anchor id="prod108" xreflabel="plusOperator"/>plusOperator</para></entry>
+<entry align="right" valign="top"><para><anchor id="prod109" xreflabel="plusOperator"/>plusOperator</para></entry>
<entry align="left" valign="top"><para>::=
( <PLUS> | <MINUS> )</para></entry></row>
<row>
-<entry align="right" valign="top"><para><anchor id="prod107" xreflabel="timesExpression"/>timesExpression</para></entry>
+<entry align="right" valign="top"><para><anchor id="prod108" xreflabel="timesExpression"/>timesExpression</para></entry>
<entry align="left" valign="top"><para>::=
-( <link linkend="prod109">valueExpressionPrimary</link> ( <link linkend="prod110">timesOperator</link> <link linkend="prod109">valueExpressionPrimary</link> )* )</para></entry></row>
+( <link linkend="prod110">valueExpressionPrimary</link> ( <link linkend="prod111">timesOperator</link> <link linkend="prod110">valueExpressionPrimary</link> )* )</para></entry></row>
<row>
-<entry align="right" valign="top"><para><anchor id="prod110" xreflabel="timesOperator"/>timesOperator</para></entry>
+<entry align="right" valign="top"><para><anchor id="prod111" xreflabel="timesOperator"/>timesOperator</para></entry>
<entry align="left" valign="top"><para>::=
( <STAR> | <SLASH> )</para></entry></row>
<row>
-<entry align="right" valign="top"><para><anchor id="prod109" xreflabel="valueExpressionPrimary"/>valueExpressionPrimary</para></entry>
+<entry align="right" valign="top"><para><anchor id="prod110" xreflabel="valueExpressionPrimary"/>valueExpressionPrimary</para></entry>
<entry align="left" valign="top"><para>::=
-( <QMARK> | <POS_REF> | <link linkend="prod111">literal</link> | ( <LBRACE> <link linkend="prod11">nonReserved</link> <link linkend="prod112">function</link> <RBRACE> ) | ( <link linkend="prod68">textAgg</link> ( <link linkend="prod113">windowSpecification</link> )? ) | ( <link linkend="prod70">aggregateSymbol</link> ( <link linkend="prod113">windowSpecification</link> )? ) | ( <link linkend="prod70">aggregateSymbol</link> ( <link linkend="prod113">windowSpecification</link> )? ) | <link linkend="prod66">orderedAgg</link> ( <link linkend="prod113">windowSpecification</link> )? | ( <link linkend="prod70">aggregateSymbol</link> <link linkend="prod113">windowSpecification</link> ) | ( <link linkend="prod112">function</link> ) | ( <ID> ( <LSBRACE> <link linkend="prod84">intVal</link> <RSBRACE> )? ) | <link linkend="prod100">subquery</link> | ( <LPAREN> <link linkend="prod24">expression</link> <RPAREN> ( <LSBRACE> <link!
linkend="prod84">intVal</link> <RSBRACE> )? ) | <link linkend="prod114">searchedCaseExpression</link> | <link linkend="prod115">caseExpression</link> )</para></entry></row>
+( <QMARK> | <POS_REF> | <link linkend="prod112">literal</link> | ( <LBRACE> <link linkend="prod11">nonReserved</link> <link linkend="prod113">function</link> <RBRACE> ) | ( <link linkend="prod68">textAgg</link> ( <link linkend="prod114">windowSpecification</link> )? ) | ( <link linkend="prod70">aggregateSymbol</link> ( <link linkend="prod114">windowSpecification</link> )? ) | ( <link linkend="prod70">aggregateSymbol</link> ( <link linkend="prod114">windowSpecification</link> )? ) | <link linkend="prod66">orderedAgg</link> ( <link linkend="prod114">windowSpecification</link> )? | ( <link linkend="prod70">aggregateSymbol</link> <link linkend="prod114">windowSpecification</link> ) | ( <link linkend="prod113">function</link> ) | ( <ID> ( <LSBRACE> <link linkend="prod84">intVal</link> <RSBRACE> )? ) | <link linkend="prod101">subquery</link> | ( <LPAREN> <link linkend="prod24">expression</link> <RPAREN> ( <LSBRACE> <link!
linkend="prod84">intVal</link> <RSBRACE> )? ) | <link linkend="prod115">searchedCaseExpression</link> | <link linkend="prod116">caseExpression</link> )</para></entry></row>
<row>
-<entry align="right" valign="top"><para><anchor id="prod113" xreflabel="windowSpecification"/>windowSpecification</para></entry>
+<entry align="right" valign="top"><para><anchor id="prod114" xreflabel="windowSpecification"/>windowSpecification</para></entry>
<entry align="left" valign="top"><para>::=
<OVER> <LPAREN> ( <PARTITION> <BY> <link linkend="prod48">expressionList</link> )? ( <link linkend="prod53">orderby</link> )? <RPAREN></para></entry></row>
<row>
-<entry align="right" valign="top"><para><anchor id="prod115" xreflabel="caseExpression"/>caseExpression</para></entry>
+<entry align="right" valign="top"><para><anchor id="prod116" xreflabel="caseExpression"/>caseExpression</para></entry>
<entry align="left" valign="top"><para>::=
<CASE> <link linkend="prod24">expression</link> ( <WHEN> <link linkend="prod24">expression</link> <THEN> <link linkend="prod24">expression</link> )+ ( <ELSE> <link linkend="prod24">expression</link> )? <END></para></entry></row>
<row>
-<entry align="right" valign="top"><para><anchor id="prod114" xreflabel="searchedCaseExpression"/>searchedCaseExpression</para></entry>
+<entry align="right" valign="top"><para><anchor id="prod115" xreflabel="searchedCaseExpression"/>searchedCaseExpression</para></entry>
<entry align="left" valign="top"><para>::=
<CASE> ( <WHEN> <link linkend="prod35">criteria</link> <THEN> <link linkend="prod24">expression</link> )+ ( <ELSE> <link linkend="prod24">expression</link> )? <END></para></entry></row>
<row>
-<entry align="right" valign="top"><para><anchor id="prod112" xreflabel="function"/>function</para></entry>
+<entry align="right" valign="top"><para><anchor id="prod113" xreflabel="function"/>function</para></entry>
<entry align="left" valign="top"><para>::=
-( ( <CONVERT> <LPAREN> <link linkend="prod24">expression</link> <COMMA> <link linkend="prod38">dataType</link> <RPAREN> ) | ( <CAST> <LPAREN> <link linkend="prod24">expression</link> <AS> <link linkend="prod38">dataType</link> <RPAREN> ) | ( <link linkend="prod11">nonReserved</link> <LPAREN> <link linkend="prod24">expression</link> <COMMA> <link linkend="prod116">stringConstant</link> <RPAREN> ) | ( <link linkend="prod11">nonReserved</link> <LPAREN> <link linkend="prod117">intervalType</link> <COMMA> <link linkend="prod24">expression</link> <COMMA> <link linkend="prod24">expression</link> <RPAREN> ) | <link linkend="prod118">queryString</link> | ( ( <LEFT> | <RIGHT> | <CHAR> | <USER> | <YEAR> | <MONTH> | <HOUR> | <MINUTE> | <SECOND> | <XMLCONCAT> | <XMLCOMMENT> ) <LPAREN> ( <link linkend="prod48">expressionList</li!
nk> )? <RPAREN> ) | ( ( <TRANSLATE> | <INSERT> ) <LPAREN> ( <link linkend="prod48">expressionList</link> )? <RPAREN> ) | <link linkend="prod119">xmlParse</link> | <link linkend="prod120">xmlElement</link> | ( <XMLPI> <LPAREN> ( <ID> <link linkend="prod121">idExpression</link> | <link linkend="prod121">idExpression</link> ) ( <COMMA> <link linkend="prod24">expression</link> )? <RPAREN> ) | <link linkend="prod122">xmlForest</link> | <link linkend="prod82">xmlSerialize</link> | <link linkend="prod85">xmlQuery</link> | ( <link linkend="prod2">id</link> <LPAREN> ( <link linkend="prod48">expressionList</link> )? <RPAREN> ) )</para></entry></row>
+( ( <CONVERT> <LPAREN> <link linkend="prod24">expression</link> <COMMA> <link linkend="prod38">dataType</link> <RPAREN> ) | ( <CAST> <LPAREN> <link linkend="prod24">expression</link> <AS> <link linkend="prod38">dataType</link> <RPAREN> ) | ( <link linkend="prod11">nonReserved</link> <LPAREN> <link linkend="prod24">expression</link> <FROM> <link linkend="prod24">expression</link> ( <FOR> <link linkend="prod24">expression</link> )? <RPAREN> ) | ( <link linkend="prod11">nonReserved</link> <LPAREN> ( <YEAR> | <MONTH> | <DAY> | <HOUR> | <MINUTE> | <SECOND> ) <FROM> <link linkend="prod24">expression</link> <RPAREN> ) | ( <link linkend="prod11">nonReserved</link> <LPAREN> ( ( ( ( <LEADING> | <TRAILING> | <BOTH> ) ( <link linkend="prod24">expression</link> )? ) | <link linkend="prod24">expression</link> ) <FROM> )? <link linkend!
="prod24">expression</link> <RPAREN> ) | ( <link linkend="prod11">nonReserved</link> <LPAREN> <link linkend="prod24">expression</link> <COMMA> <link linkend="prod117">stringConstant</link> <RPAREN> ) | ( <link linkend="prod11">nonReserved</link> <LPAREN> <link linkend="prod118">intervalType</link> <COMMA> <link linkend="prod24">expression</link> <COMMA> <link linkend="prod24">expression</link> <RPAREN> ) | <link linkend="prod119">queryString</link> | ( ( <LEFT> | <RIGHT> | <CHAR> | <USER> | <YEAR> | <MONTH> | <HOUR> | <MINUTE> | <SECOND> | <XMLCONCAT> | <XMLCOMMENT> ) <LPAREN> ( <link linkend="prod48">expressionList</link> )? <RPAREN> ) | ( ( <TRANSLATE> | <INSERT> ) <LPAREN> ( <link linkend="prod48">expressionList</link> )? <RPAREN> ) | <link linkend="prod120">xmlParse</link> | <link linkend="prod121">xmlElement</link> | ( &l!
t;XMLPI> <LPAREN> ( <ID> <link linkend="prod122!
">idExpr
ession</link> | <link linkend="prod122">idExpression</link> ) ( <COMMA> <link linkend="prod24">expression</link> )? <RPAREN> ) | <link linkend="prod123">xmlForest</link> | <link linkend="prod82">xmlSerialize</link> | <link linkend="prod85">xmlQuery</link> | ( <link linkend="prod2">id</link> <LPAREN> ( <link linkend="prod48">expressionList</link> )? <RPAREN> ) )</para></entry></row>
<row>
-<entry align="right" valign="top"><para><anchor id="prod116" xreflabel="stringConstant"/>stringConstant</para></entry>
+<entry align="right" valign="top"><para><anchor id="prod117" xreflabel="stringConstant"/>stringConstant</para></entry>
<entry align="left" valign="top"><para>::=
<link linkend="prod1">stringVal</link></para></entry></row>
<row>
-<entry align="right" valign="top"><para><anchor id="prod119" xreflabel="xmlParse"/>xmlParse</para></entry>
+<entry align="right" valign="top"><para><anchor id="prod120" xreflabel="xmlParse"/>xmlParse</para></entry>
<entry align="left" valign="top"><para>::=
<XMLPARSE> <LPAREN> <link linkend="prod11">nonReserved</link> <link linkend="prod24">expression</link> ( <link linkend="prod11">nonReserved</link> )? <RPAREN></para></entry></row>
<row>
-<entry align="right" valign="top"><para><anchor id="prod118" xreflabel="queryString"/>queryString</para></entry>
+<entry align="right" valign="top"><para><anchor id="prod119" xreflabel="queryString"/>queryString</para></entry>
<entry align="left" valign="top"><para>::=
<link linkend="prod11">nonReserved</link> <LPAREN> <link linkend="prod24">expression</link> ( <COMMA> <link linkend="prod65">derivedColumn</link> )* <RPAREN></para></entry></row>
<row>
-<entry align="right" valign="top"><para><anchor id="prod120" xreflabel="xmlElement"/>xmlElement</para></entry>
+<entry align="right" valign="top"><para><anchor id="prod121" xreflabel="xmlElement"/>xmlElement</para></entry>
<entry align="left" valign="top"><para>::=
-<XMLELEMENT> <LPAREN> ( <ID> <link linkend="prod2">id</link> | <link linkend="prod2">id</link> ) ( <COMMA> <link linkend="prod86">xmlNamespaces</link> )? ( <COMMA> <link linkend="prod123">xmlAttributes</link> )? ( <COMMA> <link linkend="prod24">expression</link> )* <RPAREN></para></entry></row>
+<XMLELEMENT> <LPAREN> ( <ID> <link linkend="prod2">id</link> | <link linkend="prod2">id</link> ) ( <COMMA> <link linkend="prod86">xmlNamespaces</link> )? ( <COMMA> <link linkend="prod124">xmlAttributes</link> )? ( <COMMA> <link linkend="prod24">expression</link> )* <RPAREN></para></entry></row>
<row>
-<entry align="right" valign="top"><para><anchor id="prod123" xreflabel="xmlAttributes"/>xmlAttributes</para></entry>
+<entry align="right" valign="top"><para><anchor id="prod124" xreflabel="xmlAttributes"/>xmlAttributes</para></entry>
<entry align="left" valign="top"><para>::=
<XMLATTRIBUTES> <LPAREN> <link linkend="prod65">derivedColumn</link> ( <COMMA> <link linkend="prod65">derivedColumn</link> )* <RPAREN></para></entry></row>
<row>
-<entry align="right" valign="top"><para><anchor id="prod122" xreflabel="xmlForest"/>xmlForest</para></entry>
+<entry align="right" valign="top"><para><anchor id="prod123" xreflabel="xmlForest"/>xmlForest</para></entry>
<entry align="left" valign="top"><para>::=
<XMLFOREST> <LPAREN> ( <link linkend="prod86">xmlNamespaces</link> <COMMA> )? <link linkend="prod65">derivedColumn</link> ( <COMMA> <link linkend="prod65">derivedColumn</link> )* <RPAREN></para></entry></row>
<row>
<entry align="right" valign="top"><para><anchor id="prod86" xreflabel="xmlNamespaces"/>xmlNamespaces</para></entry>
<entry align="left" valign="top"><para>::=
-<XMLNAMESPACES> <LPAREN> <link linkend="prod124">namespaceItem</link> ( <COMMA> <link linkend="prod124">namespaceItem</link> )* <RPAREN></para></entry></row>
+<XMLNAMESPACES> <LPAREN> <link linkend="prod125">namespaceItem</link> ( <COMMA> <link linkend="prod125">namespaceItem</link> )* <RPAREN></para></entry></row>
<row>
-<entry align="right" valign="top"><para><anchor id="prod124" xreflabel="namespaceItem"/>namespaceItem</para></entry>
+<entry align="right" valign="top"><para><anchor id="prod125" xreflabel="namespaceItem"/>namespaceItem</para></entry>
<entry align="left" valign="top"><para>::=
( <link linkend="prod1">stringVal</link> <AS> <link linkend="prod2">id</link> )</para></entry></row>
<row>
@@ -883,7 +888,7 @@
<entry align="left" valign="top"><para>::=
( <DEFAULT_KEYWORD> <link linkend="prod1">stringVal</link> )</para></entry></row>
<row>
-<entry align="right" valign="top"><para><anchor id="prod121" xreflabel="idExpression"/>idExpression</para></entry>
+<entry align="right" valign="top"><para><anchor id="prod122" xreflabel="idExpression"/>idExpression</para></entry>
<entry align="left" valign="top"><para>::=
<link linkend="prod2">id</link></para></entry></row>
<row>
@@ -895,11 +900,11 @@
<entry align="left" valign="top"><para>::=
<link linkend="prod22">dataTypeString</link></para></entry></row>
<row>
-<entry align="right" valign="top"><para><anchor id="prod117" xreflabel="intervalType"/>intervalType</para></entry>
+<entry align="right" valign="top"><para><anchor id="prod118" xreflabel="intervalType"/>intervalType</para></entry>
<entry align="left" valign="top"><para>::=
( <link linkend="prod11">nonReserved</link> )</para></entry></row>
<row>
-<entry align="right" valign="top"><para><anchor id="prod111" xreflabel="literal"/>literal</para></entry>
+<entry align="right" valign="top"><para><anchor id="prod112" xreflabel="literal"/>literal</para></entry>
<entry align="left" valign="top"><para>::=
( <link linkend="prod1">stringVal</link> | <INTEGERVAL> | <FLOATVAL> | <FALSE> | <TRUE> | <UNKNOWN> | <NULL> | ( ( <BOOLEANTYPE> | <TIMESTAMPTYPE> | <DATETYPE> | <TIMETYPE> ) <link linkend="prod1">stringVal</link> <RBRACE> ) )</para></entry></row>
</tbody>
Modified: trunk/documentation/reference/src/main/docbook/en-US/content/scalar_functions.xml
===================================================================
--- trunk/documentation/reference/src/main/docbook/en-US/content/scalar_functions.xml 2011-08-04 17:51:11 UTC (rev 3363)
+++ trunk/documentation/reference/src/main/docbook/en-US/content/scalar_functions.xml 2011-08-05 18:33:39 UTC (rev 3364)
@@ -1208,6 +1208,21 @@
</row>
<row>
<entry>
+ <para>EXTRACT(YEAR|MONTH|DAY|HOUR|MINUTE|SECOND FROM x)</para>
+ </entry>
+ <entry>
+ <para>Return the given field value from the date value x.
+ Produces the same result as the assoceated YEAR, MONTH, DAYOFMONTH, HOUR, MINUTE, SECOND functions.
+ </para>
+ <para>The SQL specification also allows for TIMEZONE_HOUR and TIMEZONE_MINUTE as extraction targets.
+ In Teiid all date values are in the timezone of the server.</para>
+ </entry>
+ <entry>
+ <para>x in {date, time, timestamp}, returns integer</para>
+ </entry>
+ </row>
+ <row>
+ <entry>
<para>FORMATDATE(x, y)</para>
</entry>
<entry>
@@ -1843,100 +1858,44 @@
<section>
<title>System Functions</title>
<para>System functions provide access to information in the Teiid system from within a query. </para>
- <informaltable frame="all">
- <tgroup cols="3">
- <thead>
- <row>
- <entry>
- <para>Function</para>
- </entry>
- <entry>
- <para>Definition</para>
- </entry>
- <entry>
- <para>Datatype Constraint</para>
- </entry>
- </row>
- </thead>
- <tbody>
- <row>
- <entry>
- <para><code>COMMANDPAYLOAD()</code></para>
- </entry>
- <entry>
- <para>Retrieve the string form of the command payload
+ <section>
+ <title>COMMANDPAYLOAD</title>
+ <para>Retrieve a string from the command payload
or null if no command payload was specified. The command
payload is set by a method on the Teiid JDBC API
extensions on a per-query basis.</para>
- </entry>
- <entry>
- <para>Returns a string</para>
- </entry>
- </row>
- <row>
- <entry>
- <para><code>COMMANDPAYLOAD(key)</code></para>
- </entry>
- <entry>
- <para>Cast the command payload object to a
- java.util.Properties object and look up the specified key in
- the object</para>
- </entry>
- <entry>
- <para>key in {string}, return is string</para>
- </entry>
- </row>
- <row>
- <entry>
- <para><code>ENV(key)</code></para>
- </entry>
- <entry>
- <para>Retrieve a system environment property. The only key specific to the current session is ‘sessionid’.
+ <para><synopsis>COMMANDPAYLOAD([key])</synopsis></para>
+ <para>If the key parameter is provided, the command payload object is cast to a
+ java.util.Properties object and the corresponding property value for the key is returned. If the key is not specified the return value is the command payload object toString value.</para>
+ <para>key, return value are strings</para>
+ </section>
+ <section>
+ <title>ENV</title>
+ <para>Retrieve a system environment property.</para>
+ <para><synopsis>ENV(key)</synopsis></para>
+ <para>The only key specific to the current session is 'sessionid'.
However the preferred mechanism for getting the session id is with the session_id() function.
- To prevent untrusted access to system properties, the use of this function must be specifically enabled in the &jboss-beans; file.
- </para>
- </entry>
- <entry>
- <para>key in {string}, return is string</para>
- </entry>
- </row>
- <row>
- <entry>
- <para><code>SESSION_ID()</code></para>
- </entry>
- <entry>
- <para>Retrieve the string form of the current session id.</para>
- </entry>
- <entry>
- <para>return is string</para>
- </entry>
- </row>
- <row>
- <entry>
- <para><code>USER()</code></para>
- </entry>
- <entry>
- <para>Retrieve the name of the user executing the
- query</para>
- </entry>
- <entry>
- <para>return is string</para>
- </entry>
- </row>
- <row>
- <entry>
- <para><code>CURRENT_DATABASE()</code></para>
- </entry>
- <entry>
- <para>Retrieve the catalog name of the database. Currently VDB's name is also the catalog name.</para>
- </entry>
- <entry>
- <para>return is string</para>
- </entry>
- </row>
- </tbody>
- </tgroup>
- </informaltable>
+ To prevent untrusted access to system properties, the use of this function must be specifically enabled in the &jboss-beans; file.</para>
+ <para>key, return value are strings</para>
+ </section>
+ <section>
+ <title>SESSION_ID</title>
+ <para>Retrieve the string form of the current session id.</para>
+ <para><synopsis>SESSION_ID()</synopsis></para>
+ <para>return value is string.</para>
+ </section>
+ <section>
+ <title>USER</title>
+ <para>Retrieve the name of the user executing the query.</para>
+ <para><synopsis>USER()</synopsis></para>
+ <para>return value is string.</para>
+ </section>
+ <section>
+ <title>CURRENT_DATABASE</title>
+ <para>Retrieve the catalog name of the database. The VDB name is always the catalog name.</para>
+ <para><synopsis>CURRENT_DATABASE()</synopsis></para>
+ <para>return value is string.</para>
+ </section>
</section>
<section id="xml_functions">
<title>XML Functions</title>
Modified: trunk/documentation/reference/src/main/docbook/en-US/content/sql_support.xml
===================================================================
--- trunk/documentation/reference/src/main/docbook/en-US/content/sql_support.xml 2011-08-04 17:51:11 UTC (rev 3363)
+++ trunk/documentation/reference/src/main/docbook/en-US/content/sql_support.xml 2011-08-05 18:33:39 UTC (rev 3364)
@@ -471,50 +471,81 @@
</listitem>
</itemizedlist>
<itemizedlist>
- <para>Syntax Rules:
+ <para>Usage:
</para>
<listitem>
- <para>expression (=|<>|!=|<|>|<=|>=) (expression|((ANY|ALL|SOME) subquery))
+ <para><synopsis label="Usage">criteria AND|OR criteria</synopsis>
</para>
</listitem>
<listitem>
- <para>expression [NOT] IS NULL
+ <para><synopsis label="Usage">NOT criteria</synopsis>
</para>
</listitem>
<listitem>
- <para>expression [NOT] IN (expression[,expression]*)|subquery
+ <para><synopsis label="Usage">(criteria)</synopsis>
</para>
</listitem>
<listitem>
- <para>expression [NOT] LIKE expression [ESCAPE char]
+ <para><synopsis label="Usage">expression (=|<>|!=|<|>|<=|>=) (expression|((ANY|ALL|SOME) subquery))</synopsis>
</para>
</listitem>
<listitem>
- <para>EXISTS(subquery)
+ <para><synopsis label="Usage">expression [NOT] IS NULL</synopsis>
</para>
</listitem>
<listitem>
- <para>expression BETWEEN minExpression AND maxExpression
+ <para><synopsis label="Usage">expression [NOT] IN (expression[,expression]*)|subquery</synopsis>
</para>
</listitem>
<listitem>
- <para>criteria AND|OR criteria
+ <para><synopsis label="Usage">expression [NOT] LIKE pattern [ESCAPE char]</synopsis>
+ Matches the string expression against the given string pattern.
+ The pattern may contain % to match any number of characters and _ to match any single character. The escape character can be used to escape the match characters % and _.</para>
+ </listitem>
+ <listitem>
+ <para><synopsis label="Usage">expression [NOT] SIMILAR TO pattern [ESCAPE char]</synopsis>
+ SIMILAR TO is a cross between LIKE and standard regular expression syntax. % and _ are still used, rather than .* and . respectively.</para>
+ <note><para>Teiid does not exhaustively validate SIMILAR TO pattern values. Rather the pattern is converted to an equivalent regular expression.
+ Care should be taken not to rely on general regular expression features when using SIMILAR TO. If additional features are needed, then LIKE_REGEX should be used.
+ Usage of a non-literal pattern is discouraged as pushdown support is limited.</para></note>
+ </listitem>
+ <listitem>
+ <para><synopsis label="Usage">expression [NOT] LIKE_REGEX pattern</synopsis>
+ LIKE_REGEX allows for standard regular expression syntax to be used for matching. This differs from SIMILAR TO and LIKE in that the escape character is no longer used (\ is already the
+ standard escape mechansim in regular expressions and % and _ have no special meaning.
+ The runtime engine uses the JRE implementation of regular expressions - see the <ulink url="http://download.oracle.com/javase/6/docs/api/java/util/regex/Pattern.html">java.util.regex.Pattern</ulink> class for details.
+ <note><para>Teiid does not exhaustively validate LIKE_REGEX pattern values. It is possible to use JRE only regular expression features that are not specified by the SQL specification. Additional not all sources support
+ the same regular expression flavor or extensions. Care should be taken in pushdown situations to ensure that the pattern used will have same meaning in Teiid and across all applicable sources.</para></note>
</para>
</listitem>
<listitem>
- <para>NOT criteria
+ <para><synopsis label="Usage">EXISTS(subquery)</synopsis>
</para>
</listitem>
<listitem>
- <para>expression
+ <para><synopsis label="Usage">expression [NOT] BETWEEN minExpression AND maxExpression</synopsis>
+ Teiid converts BETWEEN into the equivalent form expression >= minExpression AND expression <= maxExpression
</para>
</listitem>
<listitem>
- <para>Criteria may be nested using parenthesis.
+ <para><synopsis label="Usage">expression</synopsis>
+ Where expression has type boolean.
</para>
</listitem>
</itemizedlist>
<itemizedlist>
+ <para>Syntax Rules:
+ </para>
+ <listitem>
+ <para>The precedence ordering from lowest to highest is comparison, NOT, AND, OR
+ </para>
+ </listitem>
+ <listitem>
+ <para>Criteria nested by parenthesis will be logically evaluated prior to evaluating the parent criteria.
+ </para>
+ </listitem>
+ </itemizedlist>
+ <itemizedlist>
<para>Some examples of valid criteria are:
</para>
<listitem>
Modified: trunk/engine/src/main/java/org/teiid/dqp/internal/datamgr/CapabilitiesConverter.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/dqp/internal/datamgr/CapabilitiesConverter.java 2011-08-04 17:51:11 UTC (rev 3363)
+++ trunk/engine/src/main/java/org/teiid/dqp/internal/datamgr/CapabilitiesConverter.java 2011-08-05 18:33:39 UTC (rev 3364)
@@ -103,6 +103,9 @@
tgtCaps.setCapabilitySupport(Capability.ELEMENTARY_OLAP, srcCaps.supportsAdvancedOlapOperations());
tgtCaps.setCapabilitySupport(Capability.WINDOW_FUNCTION_ORDER_BY_AGGREGATES, srcCaps.supportsWindowOrderByWithAggregates());
tgtCaps.setCapabilitySupport(Capability.QUERY_AGGREGATES_ARRAY, srcCaps.supportsArrayAgg());
+ tgtCaps.setCapabilitySupport(Capability.CRITERIA_SIMILAR, srcCaps.supportsSimilarTo());
+ tgtCaps.setCapabilitySupport(Capability.CRITERIA_LIKE_REGEX, srcCaps.supportsLikeRegex());
+
List functions = srcCaps.getSupportedFunctions();
if(functions != null && functions.size() > 0) {
Iterator iter = functions.iterator();
Modified: trunk/engine/src/main/java/org/teiid/dqp/internal/datamgr/LanguageBridgeFactory.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/dqp/internal/datamgr/LanguageBridgeFactory.java 2011-08-04 17:51:11 UTC (rev 3363)
+++ trunk/engine/src/main/java/org/teiid/dqp/internal/datamgr/LanguageBridgeFactory.java 2011-08-05 18:33:39 UTC (rev 3364)
@@ -363,10 +363,12 @@
if(criteria.getEscapeChar() != MatchCriteria.NULL_ESCAPE_CHAR) {
escapeChar = new Character(criteria.getEscapeChar());
}
- return new Like(translate(criteria.getLeftExpression()),
+ Like like = new Like(translate(criteria.getLeftExpression()),
translate(criteria.getRightExpression()),
escapeChar,
criteria.isNegated());
+ like.setMode(criteria.getMode());
+ return like;
}
In translate(SetCriteria criteria) {
Modified: trunk/engine/src/main/java/org/teiid/query/eval/Evaluator.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/eval/Evaluator.java 2011-08-04 17:51:11 UTC (rev 3363)
+++ trunk/engine/src/main/java/org/teiid/query/eval/Evaluator.java 2011-08-05 18:33:39 UTC (rev 3364)
@@ -40,7 +40,6 @@
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
-import java.util.regex.PatternSyntaxException;
import javax.xml.transform.stream.StreamResult;
@@ -68,6 +67,7 @@
import org.teiid.core.types.XMLType.Type;
import org.teiid.core.types.basic.StringToSQLXMLTransform;
import org.teiid.core.util.EquivalenceUtil;
+import org.teiid.language.Like.MatchMode;
import org.teiid.metadata.FunctionMethod.PushDown;
import org.teiid.query.QueryPlugin;
import org.teiid.query.function.FunctionDescriptor;
@@ -203,9 +203,15 @@
}
}
- private final static char[] REGEX_RESERVED = new char[] {'$', '(', ')', '*', '.', '?', '[', '\\', ']', '^', '{', '|', '}'}; //in sorted order
- private final static MatchCriteria.PatternTranslator LIKE_TO_REGEX = new MatchCriteria.PatternTranslator(".*", ".", REGEX_RESERVED, '\\'); //$NON-NLS-1$ //$NON-NLS-2$
-
+ public final static char[] REGEX_RESERVED = new char[] {'$', '(', ')', '*', '.', '?', '[', '\\', ']', '^', '{', '|', '}'}; //in sorted order
+ private final static MatchCriteria.PatternTranslator LIKE_TO_REGEX = new MatchCriteria.PatternTranslator(new char[] {'%', '_'}, new String[] {".*", "."}, REGEX_RESERVED, '\\', Pattern.DOTALL); //$NON-NLS-1$ //$NON-NLS-2$
+
+ private final static char[] SIMILAR_REGEX_RESERVED = new char[] {'$', '.', '\\', '^'}; //in sorted order
+ public final static MatchCriteria.PatternTranslator SIMILAR_TO_REGEX = new MatchCriteria.PatternTranslator(
+ new char[] {'%', '(', ')', '*', '?', '+', '[', ']', '_', '{', '|', '}'},
+ new String[] {"([a]|[^a])*", "(", ")", "*", "?", "+", //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ //$NON-NLS-6$
+ "[", "]", "([a]|[^a])", "{", "|", "}"}, SIMILAR_REGEX_RESERVED, '\\', 0); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ //$NON-NLS-6$
+
private Map elements;
protected ProcessorDataManager dataMgr;
@@ -404,27 +410,31 @@
return null;
}
- result = match(rightValue, criteria.getEscapeChar(), leftValue);
+ result = match(rightValue, criteria.getEscapeChar(), leftValue, criteria.getMode());
return Boolean.valueOf(result ^ criteria.isNegated());
}
- private boolean match(String pattern, char escape, CharSequence search)
+ private boolean match(String pattern, char escape, CharSequence search, MatchMode mode)
throws ExpressionEvaluationException {
- StringBuffer rePattern = LIKE_TO_REGEX.translate(pattern, escape);
+ Pattern patternRegex = null;
+ switch (mode) {
+ case LIKE:
+ patternRegex = LIKE_TO_REGEX.translate(pattern, escape);
+ break;
+ case SIMILAR:
+ patternRegex = SIMILAR_TO_REGEX.translate(pattern, escape);
+ break;
+ case REGEX:
+ patternRegex = MatchCriteria.getPattern(pattern, pattern, 0);
+ break;
+ default:
+ throw new AssertionError();
+ }
- // Insert leading and trailing characters to ensure match of full string
- rePattern.insert(0, '^');
- rePattern.append('$');
-
- try {
- Pattern patternRegex = Pattern.compile(rePattern.toString(), Pattern.DOTALL);
- Matcher matcher = patternRegex.matcher(search);
- return matcher.matches();
- } catch(PatternSyntaxException e) {
- throw new ExpressionEvaluationException(e, "ERR.015.006.0014", QueryPlugin.Util.getString("ERR.015.006.0014", new Object[]{pattern, e.getMessage()})); //$NON-NLS-1$ //$NON-NLS-2$
- }
+ Matcher matcher = patternRegex.matcher(search);
+ return matcher.matches();
}
private Boolean evaluate(AbstractSetCriteria criteria, List<?> tuple)
Modified: trunk/engine/src/main/java/org/teiid/query/metadata/TempCapabilitiesFinder.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/metadata/TempCapabilitiesFinder.java 2011-08-04 17:51:11 UTC (rev 3363)
+++ trunk/engine/src/main/java/org/teiid/query/metadata/TempCapabilitiesFinder.java 2011-08-05 18:33:39 UTC (rev 3364)
@@ -52,6 +52,8 @@
tempCaps.setCapabilitySupport(Capability.CRITERIA_ISNULL, true);
tempCaps.setCapabilitySupport(Capability.CRITERIA_LIKE, true);
tempCaps.setCapabilitySupport(Capability.CRITERIA_LIKE_ESCAPE, true);
+ tempCaps.setCapabilitySupport(Capability.CRITERIA_LIKE_REGEX, true);
+ tempCaps.setCapabilitySupport(Capability.CRITERIA_SIMILAR, true);
tempCaps.setCapabilitySupport(Capability.QUERY_AGGREGATES_COUNT_STAR, true);
}
return tempCaps;
Modified: trunk/engine/src/main/java/org/teiid/query/optimizer/capabilities/SourceCapabilities.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/optimizer/capabilities/SourceCapabilities.java 2011-08-04 17:51:11 UTC (rev 3363)
+++ trunk/engine/src/main/java/org/teiid/query/optimizer/capabilities/SourceCapabilities.java 2011-08-05 18:33:39 UTC (rev 3364)
@@ -324,7 +324,9 @@
ADVANCED_OLAP,
QUERY_AGGREGATES_ARRAY,
ELEMENTARY_OLAP,
- WINDOW_FUNCTION_ORDER_BY_AGGREGATES
+ WINDOW_FUNCTION_ORDER_BY_AGGREGATES,
+ CRITERIA_SIMILAR,
+ CRITERIA_LIKE_REGEX
}
public enum Scope {
Modified: trunk/engine/src/main/java/org/teiid/query/optimizer/relational/rules/CriteriaCapabilityValidatorVisitor.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/optimizer/relational/rules/CriteriaCapabilityValidatorVisitor.java 2011-08-04 17:51:11 UTC (rev 3363)
+++ trunk/engine/src/main/java/org/teiid/query/optimizer/relational/rules/CriteriaCapabilityValidatorVisitor.java 2011-08-05 18:33:39 UTC (rev 3364)
@@ -270,18 +270,32 @@
}
public void visit(MatchCriteria obj) {
- // Check if compares are allowed
- if(! this.caps.supportsCapability(Capability.CRITERIA_LIKE)) {
- markInvalid(obj, "Like is not supported by source"); //$NON-NLS-1$
- return;
- }
+ switch (obj.getMode()) {
+ case LIKE:
+ if(! this.caps.supportsCapability(Capability.CRITERIA_LIKE)) {
+ markInvalid(obj, "Like is not supported by source"); //$NON-NLS-1$
+ return;
+ }
+ break;
+ case SIMILAR:
+ if(! this.caps.supportsCapability(Capability.CRITERIA_SIMILAR)) {
+ markInvalid(obj, "Similar to is not supported by source"); //$NON-NLS-1$
+ return;
+ }
+ break;
+ case REGEX:
+ if(! this.caps.supportsCapability(Capability.CRITERIA_LIKE_REGEX)) {
+ markInvalid(obj, "Like_regex is not supported by source"); //$NON-NLS-1$
+ return;
+ }
+ break;
+ }
// Check ESCAPE char if necessary
- if(obj.getEscapeChar() != MatchCriteria.NULL_ESCAPE_CHAR) {
- if(! this.caps.supportsCapability(Capability.CRITERIA_LIKE_ESCAPE)) {
- markInvalid(obj, "Like escape is not supported by source"); //$NON-NLS-1$
- return;
- }
+ if(obj.getEscapeChar() != MatchCriteria.NULL_ESCAPE_CHAR
+ && ! this.caps.supportsCapability(Capability.CRITERIA_LIKE_ESCAPE)) {
+ markInvalid(obj, "Like escape is not supported by source"); //$NON-NLS-1$
+ return;
}
//check NOT
Modified: trunk/engine/src/main/java/org/teiid/query/optimizer/relational/rules/NewCalculateCostUtil.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/optimizer/relational/rules/NewCalculateCostUtil.java 2011-08-04 17:51:11 UTC (rev 3363)
+++ trunk/engine/src/main/java/org/teiid/query/optimizer/relational/rules/NewCalculateCostUtil.java 2011-08-05 18:33:39 UTC (rev 3364)
@@ -43,6 +43,7 @@
import org.teiid.common.buffer.BufferManager;
import org.teiid.core.TeiidComponentException;
import org.teiid.core.types.DataTypeManager;
+import org.teiid.language.Like.MatchMode;
import org.teiid.logging.LogConstants;
import org.teiid.logging.LogManager;
import org.teiid.query.QueryPlugin;
@@ -917,7 +918,8 @@
Expression matchExpression = criteria.getRightExpression();
if(matchExpression instanceof Constant && ((Constant)matchExpression).getType().equals(DataTypeManager.DefaultDataClasses.STRING)) {
String compareValue = (String) ((Constant)matchExpression).getValue();
- if(compareValue != null && compareValue.indexOf('%') < 0) {
+ if(criteria.getMode() != MatchMode.REGEX && criteria.getEscapeChar() == MatchCriteria.NULL_ESCAPE_CHAR
+ && compareValue != null && compareValue.indexOf('%') < 0) {
return (childCost / 2) * (1 / 3f + 1 / ndv); //without knowing length constraints we'll make an average guess
}
} else if (EvaluatableVisitor.willBecomeConstant(criteria.getLeftExpression())) {
Modified: trunk/engine/src/main/java/org/teiid/query/rewriter/QueryRewriter.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/rewriter/QueryRewriter.java 2011-08-04 17:51:11 UTC (rev 3363)
+++ trunk/engine/src/main/java/org/teiid/query/rewriter/QueryRewriter.java 2011-08-05 18:33:39 UTC (rev 3364)
@@ -56,6 +56,7 @@
import org.teiid.core.util.Assertion;
import org.teiid.core.util.TimestampWithTimezone;
import org.teiid.language.SQLConstants;
+import org.teiid.language.Like.MatchMode;
import org.teiid.language.SQLConstants.NonReserved;
import org.teiid.query.QueryPlugin;
import org.teiid.query.eval.Evaluator;
@@ -2023,24 +2024,34 @@
Constant constant = (Constant) rightExpr;
String value = (String) constant.getValue();
- char escape = criteria.getEscapeChar();
-
- // Check whether escape char is unnecessary and remove it
- if(escape != MatchCriteria.NULL_ESCAPE_CHAR && value.indexOf(escape) < 0) {
- criteria.setEscapeChar(MatchCriteria.NULL_ESCAPE_CHAR);
+ if (criteria.getMode() != MatchMode.REGEX) {
+ char escape = criteria.getEscapeChar();
+
+ // Check whether escape char is unnecessary and remove it
+ if(escape != MatchCriteria.NULL_ESCAPE_CHAR && value.indexOf(escape) < 0) {
+ criteria.setEscapeChar(MatchCriteria.NULL_ESCAPE_CHAR);
+ }
+
+ // if the value of this string constant is '%', then we know the crit will
+ // always be true
+ if ( value.equals( String.valueOf(MatchCriteria.WILDCARD_CHAR)) ) {
+ return getSimpliedCriteria(criteria, criteria.getLeftExpression(), !criteria.isNegated(), true);
+ }
+
+ if (criteria.getMode() == MatchMode.SIMILAR) {
+ //regex is more widely supported
+ criteria.setMode(MatchMode.REGEX);
+ criteria.setRightExpression(new Constant(Evaluator.SIMILAR_TO_REGEX.getPatternString(value, escape)));
+ criteria.setEscapeChar(MatchCriteria.NULL_ESCAPE_CHAR);
+ } else if(DataTypeManager.DefaultDataClasses.STRING.equals(criteria.getLeftExpression().getType())
+ && value.indexOf(escape) < 0
+ && value.indexOf(MatchCriteria.MATCH_CHAR) < 0
+ && value.indexOf(MatchCriteria.WILDCARD_CHAR) < 0) {
+ // if both left and right expressions are strings, and the LIKE match characters ('*', '_') are not present
+ // in the right expression, rewrite the criteria as EQUALs rather than LIKE
+ return rewriteCriteria(new CompareCriteria(criteria.getLeftExpression(), criteria.isNegated()?CompareCriteria.NE:CompareCriteria.EQ, criteria.getRightExpression()));
+ }
}
-
- // if the value of this string constant is '%', then we know the crit will
- // always be true
- if ( value.equals( String.valueOf(MatchCriteria.WILDCARD_CHAR)) ) {
- return getSimpliedCriteria(criteria, criteria.getLeftExpression(), !criteria.isNegated(), true);
- }
-
- // if both left and right expressions are strings, and the LIKE match characters ('*', '_') are not present
- // in the right expression, rewrite the criteria as EQUALs rather than LIKE
- if(DataTypeManager.DefaultDataClasses.STRING.equals(criteria.getLeftExpression().getType()) && value.indexOf(escape) < 0 && value.indexOf(MatchCriteria.MATCH_CHAR) < 0 && value.indexOf(MatchCriteria.WILDCARD_CHAR) < 0) {
- return rewriteCriteria(new CompareCriteria(criteria.getLeftExpression(), criteria.isNegated()?CompareCriteria.NE:CompareCriteria.EQ, criteria.getRightExpression()));
- }
}
return criteria;
Modified: trunk/engine/src/main/java/org/teiid/query/sql/lang/MatchCriteria.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/sql/lang/MatchCriteria.java 2011-08-04 17:51:11 UTC (rev 3363)
+++ trunk/engine/src/main/java/org/teiid/query/sql/lang/MatchCriteria.java 2011-08-05 18:33:39 UTC (rev 3364)
@@ -23,10 +23,15 @@
package org.teiid.query.sql.lang;
import java.util.Arrays;
+import java.util.List;
+import java.util.regex.Pattern;
+import java.util.regex.PatternSyntaxException;
import org.teiid.api.exception.query.ExpressionEvaluationException;
import org.teiid.core.util.EquivalenceUtil;
import org.teiid.core.util.HashCodeUtil;
+import org.teiid.core.util.LRUCache;
+import org.teiid.language.Like.MatchMode;
import org.teiid.query.QueryPlugin;
import org.teiid.query.sql.LanguageVisitor;
import org.teiid.query.sql.lang.PredicateCriteria.Negatable;
@@ -61,7 +66,8 @@
private char escapeChar = NULL_ESCAPE_CHAR;
/** Negation flag. Indicates whether the criteria expression contains a NOT. */
- private boolean negated = false;
+ private boolean negated;
+ private MatchMode mode = MatchMode.LIKE;
/**
* Constructs a default instance of this class.
@@ -200,10 +206,14 @@
MatchCriteria mc = (MatchCriteria)obj;
- if (isNegated() ^ mc.isNegated()) {
+ if (isNegated() != mc.isNegated()) {
return false;
}
+ if (this.mode != mc.mode) {
+ return false;
+ }
+
return getEscapeChar() == mc.getEscapeChar() &&
EquivalenceUtil.areEqual(getLeftExpression(), mc.getLeftExpression()) &&
EquivalenceUtil.areEqual(getRightExpression(), mc.getRightExpression());
@@ -224,18 +234,36 @@
}
MatchCriteria criteriaCopy = new MatchCriteria(leftCopy, rightCopy, getEscapeChar());
criteriaCopy.setNegated(isNegated());
+ criteriaCopy.mode = mode;
return criteriaCopy;
}
+ private final static LRUCache<List<?>, Pattern> patternCache = new LRUCache<List<?>, Pattern>(100);
+
+ public static Pattern getPattern(String newPattern, String originalPattern, int flags) throws ExpressionEvaluationException {
+ List<?> key = Arrays.asList(newPattern, flags);
+ Pattern p = patternCache.get(key);
+ if (p == null) {
+ try {
+ p = Pattern.compile(newPattern, Pattern.DOTALL);
+ patternCache.put(key, p);
+ } catch(PatternSyntaxException e) {
+ throw new ExpressionEvaluationException(e, "ERR.015.006.0014", QueryPlugin.Util.getString("ERR.015.006.0014", new Object[]{originalPattern, e.getMessage()})); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+ }
+ return p;
+ }
+
/**
* <p>Utility to convert the pattern into a different match syntax</p>
*/
public static class PatternTranslator {
-
private char[] reserved;
private char newEscape;
- private String newWildCard;
- private String newSingleMatch;
+ private char[] toReplace;
+ private String[] replacements;
+ private int flags;
+ private final LRUCache<List<?>, Pattern> cache = new LRUCache<List<?>, Pattern>(100);
/**
* @param newWildCard replacement for %
@@ -243,17 +271,29 @@
* @param reserved sorted array of reserved chars in the new match syntax
* @param newEscape escape char in the new syntax
*/
- public PatternTranslator(String newWildCard, String newSingleMatch, char[] reserved, char newEscape) {
+ public PatternTranslator(char[] toReplace, String[] replacements, char[] reserved, char newEscape, int flags) {
this.reserved = reserved;
this.newEscape = newEscape;
- this.newSingleMatch = newSingleMatch;
- this.newWildCard = newWildCard;
+ this.toReplace = toReplace;
+ this.replacements = replacements;
+ this.flags = flags;
}
- public StringBuffer translate(String pattern, char escape) throws ExpressionEvaluationException {
+ public Pattern translate(String pattern, char escape) throws ExpressionEvaluationException {
+ List<?> key = Arrays.asList(pattern, escape);
+ Pattern result = cache.get(key);
+ if (result == null) {
+ String newPattern = getPatternString(pattern, escape);
+ result = getPattern(newPattern, pattern, flags);
+ cache.put(key, result);
+ }
+ return result;
+ }
+
+ public String getPatternString(String pattern, char escape)
+ throws ExpressionEvaluationException {
+ StringBuffer newPattern = new StringBuffer("^"); //$NON-NLS-1$
- StringBuffer newPattern = new StringBuffer();
-
boolean escaped = false;
for (int i = 0; i < pattern.length(); i++) {
@@ -266,25 +306,21 @@
} else {
escaped = true;
}
- } else if (character == MatchCriteria.WILDCARD_CHAR) {
- if (escaped) {
- appendCharacter(newPattern, character);
- escaped = false;
- } else {
- newPattern.append(newWildCard);
- }
- } else if (character == MatchCriteria.MATCH_CHAR) {
- if (escaped) {
- appendCharacter(newPattern, character);
- escaped = false;
- } else {
- newPattern.append(newSingleMatch);
- }
} else {
- if (escaped) {
- throw new ExpressionEvaluationException(QueryPlugin.Util.getString("MatchCriteria.invalid_escape", new Object[] {pattern, new Character(escape)})); //$NON-NLS-1$
- }
- appendCharacter(newPattern, character);
+ int index = Arrays.binarySearch(toReplace, character);
+ if (index >= 0) {
+ if (escaped) {
+ appendCharacter(newPattern, character);
+ escaped = false;
+ } else {
+ newPattern.append(replacements[index]);
+ }
+ } else {
+ if (escaped) {
+ throw new ExpressionEvaluationException(QueryPlugin.Util.getString("MatchCriteria.invalid_escape", new Object[] {pattern, new Character(escape)})); //$NON-NLS-1$
+ }
+ appendCharacter(newPattern, character);
+ }
}
}
@@ -292,8 +328,9 @@
throw new ExpressionEvaluationException(QueryPlugin.Util.getString("MatchCriteria.invalid_escape", new Object[] {pattern, new Character(escape)})); //$NON-NLS-1$
}
- return newPattern;
- }
+ newPattern.append('$');
+ return newPattern.toString();
+ }
private void appendCharacter(StringBuffer newPattern, char character) {
if (Arrays.binarySearch(this.reserved, character) >= 0) {
@@ -304,4 +341,12 @@
}
+ public MatchMode getMode() {
+ return mode;
+ }
+
+ public void setMode(MatchMode mode) {
+ this.mode = mode;
+ }
+
} // END CLASS
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 2011-08-04 17:51:11 UTC (rev 3363)
+++ trunk/engine/src/main/java/org/teiid/query/sql/visitor/SQLStringVisitor.java 2011-08-05 18:33:39 UTC (rev 3364)
@@ -569,7 +569,19 @@
append(NOT);
append(SPACE);
}
- append(LIKE);
+ switch (obj.getMode()) {
+ case SIMILAR:
+ append(SIMILAR);
+ append(SPACE);
+ append(TO);
+ break;
+ case LIKE:
+ append(LIKE);
+ break;
+ case REGEX:
+ append(LIKE_REGEX);
+ break;
+ }
append(SPACE);
visitNode(obj.getRightExpression());
@@ -578,7 +590,7 @@
append(SPACE);
append(ESCAPE);
append(" '"); //$NON-NLS-1$
- append("" + obj.getEscapeChar()); //$NON-NLS-1$
+ append(String.valueOf(obj.getEscapeChar()));
append("'"); //$NON-NLS-1$
}
}
@@ -593,16 +605,16 @@
public void visit( Option obj ) {
append(OPTION);
- Collection groups = obj.getDependentGroups();
+ Collection<String> groups = obj.getDependentGroups();
if (groups != null && groups.size() > 0) {
append(" "); //$NON-NLS-1$
append(MAKEDEP);
append(" "); //$NON-NLS-1$
- Iterator iter = groups.iterator();
+ Iterator<String> iter = groups.iterator();
while (iter.hasNext()) {
- outputDisplayName((String)iter.next());
+ outputDisplayName(iter.next());
if (iter.hasNext()) {
append(", ");//$NON-NLS-1$
Modified: trunk/engine/src/main/java/org/teiid/query/tempdata/IndexInfo.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/tempdata/IndexInfo.java 2011-08-04 17:51:11 UTC (rev 3363)
+++ trunk/engine/src/main/java/org/teiid/query/tempdata/IndexInfo.java 2011-08-05 18:33:39 UTC (rev 3364)
@@ -23,6 +23,7 @@
package org.teiid.query.tempdata;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.Collection;
import java.util.Iterator;
import java.util.LinkedList;
@@ -32,8 +33,10 @@
import org.teiid.common.buffer.TupleBrowser;
import org.teiid.common.buffer.TupleSource;
import org.teiid.core.TeiidComponentException;
+import org.teiid.language.Like.MatchMode;
import org.teiid.logging.LogConstants;
import org.teiid.logging.LogManager;
+import org.teiid.query.eval.Evaluator;
import org.teiid.query.processor.CollectionTupleSource;
import org.teiid.query.processor.relational.RelationalNode;
import org.teiid.query.sql.lang.CompareCriteria;
@@ -126,22 +129,45 @@
Constant value = (Constant)matchCriteria.getRightExpression();
String pattern = (String)value.getValue();
boolean escaped = false;
+ char escapeChar = matchCriteria.getEscapeChar();
+ if (matchCriteria.getMode() == MatchMode.REGEX) {
+ escapeChar = '\\';
+ }
StringBuilder prefix = new StringBuilder();
- for (int j = 0; i < pattern.length(); j++) {
+
+ if (pattern.length() > 0 && matchCriteria.getMode() == MatchMode.REGEX && pattern.charAt(0) != '^') {
+ //make the assumption that we require an anchor
+ continue;
+ }
+
+ for (int j = matchCriteria.getMode() == MatchMode.REGEX?1:0; i < pattern.length(); j++) {
char character = pattern.charAt(j);
- if (character == matchCriteria.getEscapeChar() && character != MatchCriteria.NULL_ESCAPE_CHAR) {
+ if (character == escapeChar && character != MatchCriteria.NULL_ESCAPE_CHAR) {
if (escaped) {
prefix.append(character);
escaped = false;
} else {
escaped = true;
}
- } else if (character == MatchCriteria.WILDCARD_CHAR || character == MatchCriteria.MATCH_CHAR) {
- break;
+ continue;
+ }
+ if (!escaped) {
+ if (matchCriteria.getMode() == MatchMode.LIKE) {
+ if (character == MatchCriteria.WILDCARD_CHAR || character == MatchCriteria.MATCH_CHAR) {
+ break;
+ }
+ } else {
+ int index = Arrays.binarySearch(Evaluator.REGEX_RESERVED, character);
+ if (index >= 0 && pattern.length() > 0) {
+ getRegexPrefix(pattern, escapeChar, prefix, j, character);
+ break;
+ }
+ }
} else {
- prefix.append(character);
+ escaped = false;
}
+ prefix.append(character);
}
if (prefix.length() > 0) {
this.addCondition(i, new Constant(prefix.toString()), CompareCriteria.GE);
@@ -158,6 +184,32 @@
}
}
}
+
+ private void getRegexPrefix(String pattern, char escapeChar,
+ StringBuilder prefix, int j, char character) {
+ boolean escaped = false;
+ //check the rest of the expression for |
+ int level = 0;
+ for (int k = j; k < pattern.length(); k++) {
+ character = pattern.charAt(k);
+ if (character == escapeChar && character != MatchCriteria.NULL_ESCAPE_CHAR) {
+ escaped = !escaped;
+ } else if (!escaped) {
+ if (character == '(') {
+ level++;
+ } else if (character == ')') {
+ level--;
+ } else if (character == '|' && level == 0) {
+ prefix.setLength(0); //TODO: turn this into an IN condition
+ return;
+ }
+ }
+ }
+
+ if (character == '{' || character == '?' || character == '*') {
+ prefix.setLength(prefix.length() - 1);
+ }
+ }
void addCondition(int i, Constant value, int comparisionMode) {
switch (comparisionMode) {
Modified: trunk/engine/src/main/javacc/org/teiid/query/parser/SQLParser.jj
===================================================================
--- trunk/engine/src/main/javacc/org/teiid/query/parser/SQLParser.jj 2011-08-04 17:51:11 UTC (rev 3363)
+++ trunk/engine/src/main/javacc/org/teiid/query/parser/SQLParser.jj 2011-08-05 18:33:39 UTC (rev 3364)
@@ -23,6 +23,7 @@
import org.teiid.query.sql.symbol.*;
import org.teiid.metadata.*;
import org.teiid.metadata.BaseColumn.NullType;
+import org.teiid.language.Like.MatchMode;
/**
* <p>The SQLParser is a JavaCC-generated parser that reads a SQL string and produces a
@@ -193,6 +194,7 @@
| <LARGE: "large">
| <LEADING: "leading">
| <LIKE: "like">
+| <LIKE_REGEX: "like_regex">
| <LIMIT: "limit">
| <LOCAL: "local">
| <LOOP: "loop">
@@ -2692,6 +2694,7 @@
[(
LOOKAHEAD(2) ex=betweenCrit(info, ex) |
LOOKAHEAD(2) ex=matchCrit(info, ex) |
+ LOOKAHEAD(2) ex=regexMatchCrit(info, ex) |
ex=setCrit(info, ex) |
ex=isNullCrit(info, ex) |
LOOKAHEAD(operator() (<ANY>|<SOME>|<ALL>) subquery(info)) ex=subqueryCompareCriteria(info, ex) |
@@ -2841,13 +2844,14 @@
Character esc = null;
Expression value = null;
boolean negated = false;
+ boolean similar = false;
}
{
[<NOT> {negated = true;}]
- <LIKE>
+ (<LIKE>|(<SIMILAR> <TO> {similar = true;}))
value=commonValueExpression(info)
- [ <ESCAPE> esc = charVal(info, "LIKE ESCAPE") |
- (<LBRACE> <ESCAPE> esc = charVal(info, "LIKE ESCAPE") <RBRACE>)
+ [ <ESCAPE> esc = charVal(info, "LIKE/SIMILAR TO ESCAPE") |
+ (<LBRACE> <ESCAPE> esc = charVal(info, "LIKE/SIMILAR TO ESCAPE") <RBRACE>)
]
{
MatchCriteria matchcriteria = new MatchCriteria(expression, value);
@@ -2855,10 +2859,28 @@
if(esc != null) {
matchcriteria.setEscapeChar(esc.charValue());
}
+ matchcriteria.setMode(similar?MatchMode.SIMILAR:MatchMode.LIKE);
return matchcriteria;
}
}
+MatchCriteria regexMatchCrit(ParseInfo info, Expression expression) :
+{
+ Expression value = null;
+ boolean negated = false;
+}
+{
+ [<NOT> {negated = true;}]
+ <LIKE_REGEX>
+ value=commonValueExpression(info)
+ {
+ MatchCriteria matchcriteria = new MatchCriteria(expression, value);
+ matchcriteria.setNegated(negated);
+ matchcriteria.setMode(MatchMode.REGEX);
+ return matchcriteria;
+ }
+}
+
Character charVal(ParseInfo info, String type) :
{
String escStr = null;
@@ -3591,7 +3613,26 @@
<RPAREN>
)
|
- LOOKAHEAD(1, {getToken(1).image.equalsIgnoreCase("TRIM")}) (
+ LOOKAHEAD(2, {getToken(1).image.equalsIgnoreCase("EXTRACT")}) (
+ nonReserved("EXTRACT")
+ <LPAREN>
+ (funcToken = <YEAR> |
+ funcToken = <MONTH> |
+ funcToken = <DAY> |
+ funcToken = <HOUR> |
+ funcToken = <MINUTE> |
+ funcToken = <SECOND>)
+ <FROM> expression = expression(info)
+ {
+ if (funcToken.image.equalsIgnoreCase("DAY")) {
+ funcName = "DAYOFMONTH";
+ }
+ args.add(expression);
+ }
+ <RPAREN>
+ )
+ |
+ LOOKAHEAD(2, {getToken(1).image.equalsIgnoreCase("TRIM")}) (
funcName= nonReserved("TRIM")
<LPAREN>
{ funcToken = null; expression = null;}
Modified: trunk/engine/src/test/java/org/teiid/query/parser/TestParser.java
===================================================================
--- trunk/engine/src/test/java/org/teiid/query/parser/TestParser.java 2011-08-04 17:51:11 UTC (rev 3363)
+++ trunk/engine/src/test/java/org/teiid/query/parser/TestParser.java 2011-08-05 18:33:39 UTC (rev 3364)
@@ -2790,7 +2790,7 @@
}
@Test public void testLikeWithEscapeException(){
- helpException("SELECT a from db.g where b like '#String' escape '#1'", "Parsing error: LIKE ESCAPE value must be a single character: [#1]."); //$NON-NLS-1$ //$NON-NLS-2$
+ helpException("SELECT a from db.g where b like '#String' escape '#1'", "Parsing error: LIKE/SIMILAR TO ESCAPE value must be a single character: [#1]."); //$NON-NLS-1$ //$NON-NLS-2$
}
/** SELECT "date"."time" from db.g */
Modified: trunk/engine/src/test/java/org/teiid/query/processor/TestTempTables.java
===================================================================
--- trunk/engine/src/test/java/org/teiid/query/processor/TestTempTables.java 2011-08-04 17:51:11 UTC (rev 3363)
+++ trunk/engine/src/test/java/org/teiid/query/processor/TestTempTables.java 2011-08-05 18:33:39 UTC (rev 3364)
@@ -197,6 +197,15 @@
execute("select * from x where e1 like 'z%'", new List[0]); //$NON-NLS-1$
}
+ @Test public void testLikeRegexWithIndex() throws Exception {
+ execute("create local temporary table x (e1 string, e2 integer, primary key (e1))", new List[] {Arrays.asList(0)}); //$NON-NLS-1$
+ execute("insert into x (e2, e1) values (3, 'ab')", new List[] {Arrays.asList(1)}); //$NON-NLS-1$
+ execute("insert into x (e2, e1) values (2, 'b')", new List[] {Arrays.asList(1)}); //$NON-NLS-1$
+ execute("select * from x where e1 like_regex '^b?.*'", new List[] {Arrays.asList("ab", 3), Arrays.asList("b", 2)}); //$NON-NLS-1$
+ execute("select * from x where e1 like_regex '^ab+.*'", new List[] {Arrays.asList("ab", 3)}); //$NON-NLS-1$
+ execute("select * from x where e1 like_regex '^ab|b'", new List[] {Arrays.asList("ab", 3), Arrays.asList("b", 2)}); //$NON-NLS-1$
+ }
+
@Test public void testIsNullWithIndex() throws Exception {
execute("create local temporary table x (e1 string, e2 integer, primary key (e1))", new List[] {Arrays.asList(0)}); //$NON-NLS-1$
execute("insert into x (e2, e1) values (3, null)", new List[] {Arrays.asList(1)}); //$NON-NLS-1$
Modified: trunk/engine/src/test/java/org/teiid/query/processor/eval/TestExpressionEvaluator.java
===================================================================
--- trunk/engine/src/test/java/org/teiid/query/processor/eval/TestExpressionEvaluator.java 2011-08-04 17:51:11 UTC (rev 3363)
+++ trunk/engine/src/test/java/org/teiid/query/processor/eval/TestExpressionEvaluator.java 2011-08-05 18:33:39 UTC (rev 3364)
@@ -437,4 +437,69 @@
assertEquals("bc", Evaluator.evaluate(ex));
}
+ @Test public void testExtract() throws Exception {
+ Expression ex = TestFunctionResolving.getExpression("extract(year from cast('2011-01-01' as date))");
+ assertEquals(2011, Evaluator.evaluate(ex));
+ }
+
+ @Test public void testExtract1() throws Exception {
+ Expression ex = TestFunctionResolving.getExpression("extract(day from cast('2011-01-01' as date))");
+ assertEquals(1, Evaluator.evaluate(ex));
+ }
+
+ @Test public void testSimilarTo() throws Exception {
+ Expression ex = TestFunctionResolving.getExpression("'aaaxy' similar to 'a+%'");
+ assertEquals(Boolean.TRUE, Evaluator.evaluate(ex));
+ }
+
+ @Test public void testSimilarTo1() throws Exception {
+ Expression ex = TestFunctionResolving.getExpression("'xaay' similar to 'xa{2,3}y'");
+ assertEquals(Boolean.TRUE, Evaluator.evaluate(ex));
+ }
+
+ @Test public void testSimilarTo2() throws Exception {
+ Expression ex = TestFunctionResolving.getExpression("'xay' similar to 'xa{2,3}y'");
+ assertEquals(Boolean.FALSE, Evaluator.evaluate(ex));
+ }
+
+ @Test(expected=ExpressionEvaluationException.class) public void testSimilarTo3() throws Exception {
+ Expression ex = TestFunctionResolving.getExpression("'xay' similar to '{'");
+ assertEquals(Boolean.FALSE, Evaluator.evaluate(ex));
+ }
+
+ @Test public void testSimilarTo4() throws Exception {
+ Expression ex = TestFunctionResolving.getExpression("'xay' similar to 'xa{2,}y'");
+ assertEquals(Boolean.FALSE, Evaluator.evaluate(ex));
+ }
+
+ @Test public void testSimilarTo5() throws Exception {
+ Expression ex = TestFunctionResolving.getExpression("'x1y' similar to 'x([a-z]+|[0-9])_'");
+ assertEquals(Boolean.TRUE, Evaluator.evaluate(ex));
+ }
+
+ @Test public void testSimilarTo6() throws Exception {
+ Expression ex = TestFunctionResolving.getExpression("'xx' similar to 'x([a-z]+|[0-9])_'");
+ assertEquals(Boolean.FALSE, Evaluator.evaluate(ex));
+ }
+
+ @Test public void testLikeRegex() throws Exception {
+ Expression ex = TestFunctionResolving.getExpression("'aaaxy' like_regex 'a+.*'");
+ assertEquals(Boolean.TRUE, Evaluator.evaluate(ex));
+ }
+
+ @Test public void testLikeRegex1() throws Exception {
+ Expression ex = TestFunctionResolving.getExpression("'xaay' similar to 'xa{2,3}y'");
+ assertEquals(Boolean.TRUE, Evaluator.evaluate(ex));
+ }
+
+ @Test public void testLikeRegex2() throws Exception {
+ Expression ex = TestFunctionResolving.getExpression("'xay' like_regex 'xa{2,3}y'");
+ assertEquals(Boolean.FALSE, Evaluator.evaluate(ex));
+ }
+
+ @Test(expected=ExpressionEvaluationException.class) public void testLikeRegex3() throws Exception {
+ Expression ex = TestFunctionResolving.getExpression("'xay' like_regex '{'");
+ assertEquals(Boolean.FALSE, Evaluator.evaluate(ex));
+ }
+
}
Modified: trunk/engine/src/test/java/org/teiid/query/sql/visitor/TestSQLStringVisitor.java
===================================================================
--- trunk/engine/src/test/java/org/teiid/query/sql/visitor/TestSQLStringVisitor.java 2011-08-04 17:51:11 UTC (rev 3363)
+++ trunk/engine/src/test/java/org/teiid/query/sql/visitor/TestSQLStringVisitor.java 2011-08-05 18:33:39 UTC (rev 3364)
@@ -22,13 +22,15 @@
package org.teiid.query.sql.visitor;
+import static org.junit.Assert.*;
+
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
-import junit.framework.TestCase;
-
+import org.junit.Test;
+import org.teiid.api.exception.query.QueryParserException;
import org.teiid.client.metadata.ParameterInfo;
import org.teiid.core.types.DataTypeManager;
import org.teiid.language.SQLConstants.NonReserved;
@@ -92,15 +94,9 @@
import org.teiid.query.sql.symbol.TestSearchedCaseExpression;
import org.teiid.query.unittest.RealMetadataFactory;
+@SuppressWarnings("nls")
+public class TestSQLStringVisitor {
-public class TestSQLStringVisitor extends TestCase {
-
- // ################################## FRAMEWORK ################################
-
- public TestSQLStringVisitor(String name) {
- super(name);
- }
-
// ################################## TEST HELPERS ################################
private void helpTest(LanguageObject obj, String expectedStr) {
@@ -110,13 +106,13 @@
// ################################## ACTUAL TESTS ################################
- public void testNull() {
+ @Test public void testNull() {
String sql = SQLStringVisitor.getSQLString(null);
assertEquals("Incorrect string for null object", SQLStringVisitor.UNDEFINED, sql); //$NON-NLS-1$
}
- public void testBetweenCriteria1() {
+ @Test public void testBetweenCriteria1() {
BetweenCriteria bc = new BetweenCriteria(
new ElementSymbol("m.g.c1"), //$NON-NLS-1$
new Constant(new Integer(1000)),
@@ -124,7 +120,7 @@
helpTest(bc, "m.g.c1 BETWEEN 1000 AND 2000"); //$NON-NLS-1$
}
- public void testBetweenCriteria2() {
+ @Test public void testBetweenCriteria2() {
BetweenCriteria bc = new BetweenCriteria(
new ElementSymbol("m.g.c1"), //$NON-NLS-1$
new Constant(new Integer(1000)),
@@ -133,7 +129,7 @@
helpTest(bc, "m.g.c1 NOT BETWEEN 1000 AND 2000"); //$NON-NLS-1$
}
- public void testCompareCriteria1() {
+ @Test public void testCompareCriteria1() {
CompareCriteria cc = new CompareCriteria(
new ElementSymbol("m.g.c1"), //$NON-NLS-1$
CompareCriteria.EQ,
@@ -142,7 +138,7 @@
helpTest(cc, "m.g.c1 = 'abc'"); //$NON-NLS-1$
}
- public void testCompareCriteria2() {
+ @Test public void testCompareCriteria2() {
CompareCriteria cc = new CompareCriteria(
new ElementSymbol("m.g.c1"), //$NON-NLS-1$
CompareCriteria.NE,
@@ -151,7 +147,7 @@
helpTest(cc, "m.g.c1 <> 'abc'"); //$NON-NLS-1$
}
- public void testCompareCriteria3() {
+ @Test public void testCompareCriteria3() {
CompareCriteria cc = new CompareCriteria(
new ElementSymbol("m.g.c1"), //$NON-NLS-1$
CompareCriteria.GT,
@@ -160,7 +156,7 @@
helpTest(cc, "m.g.c1 > 'abc'"); //$NON-NLS-1$
}
- public void testCompareCriteria4() {
+ @Test public void testCompareCriteria4() {
CompareCriteria cc = new CompareCriteria(
new ElementSymbol("m.g.c1"), //$NON-NLS-1$
CompareCriteria.GE,
@@ -169,7 +165,7 @@
helpTest(cc, "m.g.c1 >= 'abc'"); //$NON-NLS-1$
}
- public void testCompareCriteria5() {
+ @Test public void testCompareCriteria5() {
CompareCriteria cc = new CompareCriteria(
new ElementSymbol("m.g.c1"), //$NON-NLS-1$
CompareCriteria.LT,
@@ -178,7 +174,7 @@
helpTest(cc, "m.g.c1 < 'abc'"); //$NON-NLS-1$
}
- public void testCompareCriteria6() {
+ @Test public void testCompareCriteria6() {
CompareCriteria cc = new CompareCriteria(
new ElementSymbol("m.g.c1"), //$NON-NLS-1$
CompareCriteria.LE,
@@ -187,7 +183,7 @@
helpTest(cc, "m.g.c1 <= 'abc'"); //$NON-NLS-1$
}
- public void testCompareCriteria7() {
+ @Test public void testCompareCriteria7() {
CompareCriteria cc = new CompareCriteria(
null,
CompareCriteria.EQ,
@@ -196,7 +192,7 @@
helpTest(cc, "<undefined> = <undefined>"); //$NON-NLS-1$
}
- public void testCompoundCriteria1() {
+ @Test public void testCompoundCriteria1() {
CompareCriteria cc = new CompareCriteria(
new ElementSymbol("m.g.c1"), //$NON-NLS-1$
CompareCriteria.EQ,
@@ -208,7 +204,7 @@
helpTest(comp, "m.g.c1 = 'abc'"); //$NON-NLS-1$
}
- public void testCompoundCriteria2() {
+ @Test public void testCompoundCriteria2() {
CompareCriteria cc1 = new CompareCriteria(
new ElementSymbol("m.g.c1"), //$NON-NLS-1$
CompareCriteria.EQ,
@@ -225,7 +221,7 @@
helpTest(comp, "(m.g.c1 = 'abc') AND (m.g.c2 = 'abc')"); //$NON-NLS-1$
}
- public void testCompoundCriteria3() {
+ @Test public void testCompoundCriteria3() {
CompareCriteria cc1 = new CompareCriteria(
new ElementSymbol("m.g.c1"), //$NON-NLS-1$
CompareCriteria.EQ,
@@ -247,7 +243,7 @@
helpTest(comp, "(m.g.c1 = 'abc') OR (m.g.c2 = 'abc') OR (m.g.c3 = 'abc')"); //$NON-NLS-1$
}
- public void testCompoundCriteria4() {
+ @Test public void testCompoundCriteria4() {
CompareCriteria cc1 = new CompareCriteria(
new ElementSymbol("m.g.c1"), //$NON-NLS-1$
CompareCriteria.EQ,
@@ -260,7 +256,7 @@
helpTest(comp, "(m.g.c1 = 'abc') OR (<undefined>)"); //$NON-NLS-1$
}
- public void testCompoundCriteria5() {
+ @Test public void testCompoundCriteria5() {
CompareCriteria cc1 = new CompareCriteria(
new ElementSymbol("m.g.c1"), //$NON-NLS-1$
CompareCriteria.EQ,
@@ -273,7 +269,7 @@
helpTest(comp, "(<undefined>) OR (m.g.c1 = 'abc')"); //$NON-NLS-1$
}
- public void testCompoundCriteria6() {
+ @Test public void testCompoundCriteria6() {
CompareCriteria cc1 = new CompareCriteria(
new ElementSymbol("m.g.c1"), //$NON-NLS-1$
CompareCriteria.EQ,
@@ -286,14 +282,14 @@
helpTest(comp, "(m.g.c1 = 'abc') OR (<undefined>)"); //$NON-NLS-1$
}
- public void testDelete1() {
+ @Test public void testDelete1() {
Delete delete = new Delete();
delete.setGroup(new GroupSymbol("m.g")); //$NON-NLS-1$
helpTest(delete, "DELETE FROM m.g"); //$NON-NLS-1$
}
- public void testDelete2() {
+ @Test public void testDelete2() {
Delete delete = new Delete();
delete.setGroup(new GroupSymbol("m.g")); //$NON-NLS-1$
delete.setCriteria(new CompareCriteria(
@@ -305,7 +301,7 @@
helpTest(delete, "DELETE FROM m.g WHERE m.g.c1 = 'abc'"); //$NON-NLS-1$
}
- public void testFrom1() {
+ @Test public void testFrom1() {
From from = new From();
from.addGroup(new GroupSymbol("m.g1")); //$NON-NLS-1$
from.addGroup(new GroupSymbol("m.g2")); //$NON-NLS-1$
@@ -313,7 +309,7 @@
helpTest(from, "FROM m.g1, m.g2"); //$NON-NLS-1$
}
- public void testFrom2() {
+ @Test public void testFrom2() {
From from = new From();
from.addClause(new UnaryFromClause(new GroupSymbol("m.g1"))); //$NON-NLS-1$
from.addClause(new JoinPredicate(
@@ -324,14 +320,14 @@
helpTest(from, "FROM m.g1, m.g2 CROSS JOIN m.g3"); //$NON-NLS-1$
}
- public void testGroupBy1() {
+ @Test public void testGroupBy1() {
GroupBy gb = new GroupBy();
gb.addSymbol(new ElementSymbol("m.g.e1")); //$NON-NLS-1$
helpTest(gb, "GROUP BY m.g.e1"); //$NON-NLS-1$
}
- public void testGroupBy2() {
+ @Test public void testGroupBy2() {
GroupBy gb = new GroupBy();
gb.addSymbol(new ElementSymbol("m.g.e1")); //$NON-NLS-1$
gb.addSymbol(new ElementSymbol("m.g.e2")); //$NON-NLS-1$
@@ -340,7 +336,7 @@
helpTest(gb, "GROUP BY m.g.e1, m.g.e2, m.g.e3"); //$NON-NLS-1$
}
- public void testInsert1() {
+ @Test public void testInsert1() {
Insert insert = new Insert();
insert.setGroup(new GroupSymbol("m.g1")); //$NON-NLS-1$
@@ -356,33 +352,33 @@
helpTest(insert, "INSERT INTO m.g1 (e1, e2) VALUES (5, 'abc')"); //$NON-NLS-1$
}
- public void testIsNullCriteria1() {
+ @Test public void testIsNullCriteria1() {
IsNullCriteria inc = new IsNullCriteria();
inc.setExpression(new Constant("abc")); //$NON-NLS-1$
helpTest(inc, "'abc' IS NULL"); //$NON-NLS-1$
}
- public void testIsNullCriteria2() {
+ @Test public void testIsNullCriteria2() {
IsNullCriteria inc = new IsNullCriteria();
inc.setExpression(new ElementSymbol("m.g.e1")); //$NON-NLS-1$
helpTest(inc, "m.g.e1 IS NULL"); //$NON-NLS-1$
}
- public void testIsNullCriteria3() {
+ @Test public void testIsNullCriteria3() {
IsNullCriteria inc = new IsNullCriteria();
helpTest(inc, "<undefined> IS NULL"); //$NON-NLS-1$
}
- public void testIsNullCriteria4() {
+ @Test public void testIsNullCriteria4() {
IsNullCriteria inc = new IsNullCriteria();
inc.setExpression(new ElementSymbol("m.g.e1")); //$NON-NLS-1$
inc.setNegated(true);
helpTest(inc, "m.g.e1 IS NOT NULL"); //$NON-NLS-1$
}
- public void testJoinPredicate1() {
+ @Test public void testJoinPredicate1() {
JoinPredicate jp = new JoinPredicate(
new UnaryFromClause(new GroupSymbol("m.g2")), //$NON-NLS-1$
new UnaryFromClause(new GroupSymbol("m.g3")), //$NON-NLS-1$
@@ -391,7 +387,7 @@
helpTest(jp, "m.g2 CROSS JOIN m.g3"); //$NON-NLS-1$
}
- public void testOptionalJoinPredicate1() {
+ @Test public void testOptionalJoinPredicate1() {
JoinPredicate jp = new JoinPredicate(
new UnaryFromClause(new GroupSymbol("m.g2")), //$NON-NLS-1$
new UnaryFromClause(new GroupSymbol("m.g3")), //$NON-NLS-1$
@@ -400,7 +396,7 @@
helpTest(jp, "/*+ optional */ (m.g2 CROSS JOIN m.g3)"); //$NON-NLS-1$
}
- public void testJoinPredicate2() {
+ @Test public void testJoinPredicate2() {
ArrayList<Criteria> crits = new ArrayList<Criteria>();
crits.add(new CompareCriteria(new ElementSymbol("m.g2.e1"), CompareCriteria.EQ, new ElementSymbol("m.g3.e1"))); //$NON-NLS-1$ //$NON-NLS-2$
JoinPredicate jp = new JoinPredicate(
@@ -412,7 +408,7 @@
helpTest(jp, "m.g2 INNER JOIN m.g3 ON m.g2.e1 = m.g3.e1"); //$NON-NLS-1$
}
- public void testJoinPredicate3() {
+ @Test public void testJoinPredicate3() {
ArrayList<Criteria> crits = new ArrayList<Criteria>();
crits.add(new CompareCriteria(new ElementSymbol("m.g2.e1"), CompareCriteria.EQ, new ElementSymbol("m.g3.e1"))); //$NON-NLS-1$ //$NON-NLS-2$
crits.add(new CompareCriteria(new ElementSymbol("m.g2.e2"), CompareCriteria.EQ, new ElementSymbol("m.g3.e2"))); //$NON-NLS-1$ //$NON-NLS-2$
@@ -425,7 +421,7 @@
helpTest(jp, "m.g2 INNER JOIN m.g3 ON m.g2.e1 = m.g3.e1 AND m.g2.e2 = m.g3.e2"); //$NON-NLS-1$
}
- public void testJoinPredicate4() {
+ @Test public void testJoinPredicate4() {
ArrayList<Criteria> crits = new ArrayList<Criteria>();
crits.add(new CompareCriteria(new ElementSymbol("m.g2.e1"), CompareCriteria.EQ, new ElementSymbol("m.g3.e1"))); //$NON-NLS-1$ //$NON-NLS-2$
JoinPredicate jp = new JoinPredicate(
@@ -442,7 +438,7 @@
helpTest(jp2, "(m.g2 INNER JOIN m.g3 ON m.g2.e1 = m.g3.e1) CROSS JOIN m.g1"); //$NON-NLS-1$
}
- public void testJoinPredicate5() {
+ @Test public void testJoinPredicate5() {
ArrayList<Criteria> crits = new ArrayList<Criteria>();
crits.add(new NotCriteria(new CompareCriteria(new ElementSymbol("m.g2.e1"), CompareCriteria.EQ, new ElementSymbol("m.g3.e1")))); //$NON-NLS-1$ //$NON-NLS-2$
JoinPredicate jp = new JoinPredicate(
@@ -454,27 +450,27 @@
helpTest(jp, "m.g2 INNER JOIN m.g3 ON NOT (m.g2.e1 = m.g3.e1)"); //$NON-NLS-1$
}
- public void testJoinType1() {
+ @Test public void testJoinType1() {
helpTest(JoinType.JOIN_CROSS, "CROSS JOIN"); //$NON-NLS-1$
}
- public void testJoinType2() {
+ @Test public void testJoinType2() {
helpTest(JoinType.JOIN_INNER, "INNER JOIN"); //$NON-NLS-1$
}
- public void testJoinType3() {
+ @Test public void testJoinType3() {
helpTest(JoinType.JOIN_RIGHT_OUTER, "RIGHT OUTER JOIN"); //$NON-NLS-1$
}
- public void testJoinType4() {
+ @Test public void testJoinType4() {
helpTest(JoinType.JOIN_LEFT_OUTER, "LEFT OUTER JOIN"); //$NON-NLS-1$
}
- public void testJoinType5() {
+ @Test public void testJoinType5() {
helpTest(JoinType.JOIN_FULL_OUTER, "FULL OUTER JOIN"); //$NON-NLS-1$
}
- public void testMatchCriteria1() {
+ @Test public void testMatchCriteria1() {
MatchCriteria mc = new MatchCriteria();
mc.setLeftExpression(new ElementSymbol("m.g.e1")); //$NON-NLS-1$
mc.setRightExpression(new Constant("abc")); //$NON-NLS-1$
@@ -482,7 +478,7 @@
helpTest(mc, "m.g.e1 LIKE 'abc'"); //$NON-NLS-1$
}
- public void testMatchCriteria2() {
+ @Test public void testMatchCriteria2() {
MatchCriteria mc = new MatchCriteria();
mc.setLeftExpression(new ElementSymbol("m.g.e1")); //$NON-NLS-1$
mc.setRightExpression(new Constant("%")); //$NON-NLS-1$
@@ -491,7 +487,7 @@
helpTest(mc, "m.g.e1 LIKE '%' ESCAPE '#'"); //$NON-NLS-1$
}
- public void testMatchCriteria3() {
+ @Test public void testMatchCriteria3() {
MatchCriteria mc = new MatchCriteria();
mc.setLeftExpression(new ElementSymbol("m.g.e1")); //$NON-NLS-1$
mc.setRightExpression(new Constant("abc")); //$NON-NLS-1$
@@ -499,22 +495,22 @@
helpTest(mc, "m.g.e1 NOT LIKE 'abc'"); //$NON-NLS-1$
}
- public void testNotCriteria1() {
+ @Test public void testNotCriteria1() {
NotCriteria not = new NotCriteria(new IsNullCriteria(new ElementSymbol("m.g.e1"))); //$NON-NLS-1$
helpTest(not, "NOT (m.g.e1 IS NULL)"); //$NON-NLS-1$
}
- public void testNotCriteria2() {
+ @Test public void testNotCriteria2() {
NotCriteria not = new NotCriteria();
helpTest(not, "NOT (<undefined>)"); //$NON-NLS-1$
}
- public void testOption1() {
+ @Test public void testOption1() {
Option option = new Option();
helpTest(option, "OPTION"); //$NON-NLS-1$
}
- public void testOption5() {
+ @Test public void testOption5() {
Option option = new Option();
option.addDependentGroup("abc"); //$NON-NLS-1$
option.addDependentGroup("def"); //$NON-NLS-1$
@@ -522,7 +518,7 @@
helpTest(option, "OPTION MAKEDEP abc, def, xyz"); //$NON-NLS-1$
}
- public void testOption6() {
+ @Test public void testOption6() {
Option option = new Option();
option.addDependentGroup("abc"); //$NON-NLS-1$
option.addDependentGroup("def"); //$NON-NLS-1$
@@ -530,7 +526,7 @@
helpTest(option, "OPTION MAKEDEP abc, def, xyz"); //$NON-NLS-1$
}
- public void testOption8() {
+ @Test public void testOption8() {
Option option = new Option();
option.addNoCacheGroup("abc"); //$NON-NLS-1$
option.addNoCacheGroup("def"); //$NON-NLS-1$
@@ -539,20 +535,20 @@
}
// related to defect 14423
- public void testOption9() {
+ @Test public void testOption9() {
Option option = new Option();
option.setNoCache(true);
helpTest(option, "OPTION NOCACHE"); //$NON-NLS-1$
}
- public void testOrderBy1() {
+ @Test public void testOrderBy1() {
OrderBy ob = new OrderBy();
ob.addVariable(new ElementSymbol("e1")); //$NON-NLS-1$
helpTest(ob, "ORDER BY e1"); //$NON-NLS-1$
}
- public void testOrderBy2() {
+ @Test public void testOrderBy2() {
OrderBy ob = new OrderBy();
ob.addVariable(new ElementSymbol("e1")); //$NON-NLS-1$
ob.addVariable(new AliasSymbol("x", new ElementSymbol("e2"))); //$NON-NLS-1$ //$NON-NLS-2$
@@ -560,7 +556,7 @@
helpTest(ob, "ORDER BY e1, x"); //$NON-NLS-1$
}
- public void testOrderBy3() {
+ @Test public void testOrderBy3() {
OrderBy ob = new OrderBy();
ob.addVariable(new ElementSymbol("e1"), OrderBy.DESC); //$NON-NLS-1$
ob.addVariable(new ElementSymbol("x"), OrderBy.DESC); //$NON-NLS-1$
@@ -568,7 +564,7 @@
helpTest(ob, "ORDER BY e1 DESC, x DESC"); //$NON-NLS-1$
}
- public void testQuery1() {
+ @Test public void testQuery1() {
Select select = new Select();
select.addSymbol(new MultipleElementSymbol());
From from = new From();
@@ -580,7 +576,7 @@
helpTest(query, "SELECT * FROM m.g"); //$NON-NLS-1$
}
- public void testQuery2() {
+ @Test public void testQuery2() {
Select select = new Select();
select.addSymbol(new MultipleElementSymbol());
From from = new From();
@@ -603,7 +599,7 @@
helpTest(query, "SELECT * FROM m.g WHERE e1 = 5 GROUP BY e1 HAVING e1 > 0 ORDER BY e1"); //$NON-NLS-1$
}
- public void testQuery3() {
+ @Test public void testQuery3() {
Select select = new Select();
select.addSymbol(new MultipleElementSymbol());
From from = new From();
@@ -624,7 +620,7 @@
helpTest(query, "SELECT * FROM m.g GROUP BY e1 HAVING e1 > 0 ORDER BY e1"); //$NON-NLS-1$
}
- public void testQuery4() {
+ @Test public void testQuery4() {
Select select = new Select();
select.addSymbol(new MultipleElementSymbol());
From from = new From();
@@ -644,7 +640,7 @@
helpTest(query, "SELECT * FROM m.g WHERE e1 = 5 HAVING e1 > 0 ORDER BY e1"); //$NON-NLS-1$
}
- public void testQuery5() {
+ @Test public void testQuery5() {
Select select = new Select();
select.addSymbol(new MultipleElementSymbol());
From from = new From();
@@ -665,7 +661,7 @@
helpTest(query, "SELECT * FROM m.g WHERE e1 = 5 GROUP BY e1 ORDER BY e1"); //$NON-NLS-1$
}
- public void testQuery6() {
+ @Test public void testQuery6() {
Select select = new Select();
select.addSymbol(new MultipleElementSymbol());
From from = new From();
@@ -685,7 +681,7 @@
helpTest(query, "SELECT * FROM m.g WHERE e1 = 5 GROUP BY e1 HAVING e1 > 0"); //$NON-NLS-1$
}
- public void testQuery7() {
+ @Test public void testQuery7() {
Select select = new Select();
select.addSymbol(new MultipleElementSymbol());
From from = new From();
@@ -708,14 +704,14 @@
helpTest(query, "SELECT * FROM m.g WHERE e1 = 5 GROUP BY e1 HAVING e1 > 0 ORDER BY e1"); //$NON-NLS-1$
}
- public void testSelect1() {
+ @Test public void testSelect1() {
Select select = new Select();
select.addSymbol(new ElementSymbol("e1")); //$NON-NLS-1$
helpTest(select, "SELECT e1"); //$NON-NLS-1$
}
- public void testSelect2() {
+ @Test public void testSelect2() {
Select select = new Select();
select.setDistinct(true);
select.addSymbol(new ElementSymbol("e1")); //$NON-NLS-1$
@@ -723,7 +719,7 @@
helpTest(select, "SELECT DISTINCT e1"); //$NON-NLS-1$
}
- public void testSelect3() {
+ @Test public void testSelect3() {
Select select = new Select();
select.addSymbol(new ElementSymbol("e1")); //$NON-NLS-1$
select.addSymbol(new ElementSymbol("e2")); //$NON-NLS-1$
@@ -731,7 +727,7 @@
helpTest(select, "SELECT e1, e2"); //$NON-NLS-1$
}
- public void testSetCriteria1() {
+ @Test public void testSetCriteria1() {
SetCriteria sc = new SetCriteria();
sc.setExpression(new ElementSymbol("e1")); //$NON-NLS-1$
sc.setValues(new ArrayList());
@@ -739,7 +735,7 @@
helpTest(sc, "e1 IN ()"); //$NON-NLS-1$
}
- public void testSetCriteria2() {
+ @Test public void testSetCriteria2() {
SetCriteria sc = new SetCriteria();
sc.setExpression(new ElementSymbol("e1")); //$NON-NLS-1$
ArrayList values = new ArrayList();
@@ -750,7 +746,7 @@
helpTest(sc, "e1 IN (e2, 'abc')"); //$NON-NLS-1$
}
- public void testSetCriteria3() {
+ @Test public void testSetCriteria3() {
SetCriteria sc = new SetCriteria();
sc.setExpression(new ElementSymbol("e1")); //$NON-NLS-1$
ArrayList values = new ArrayList();
@@ -761,7 +757,7 @@
helpTest(sc, "e1 IN (<undefined>, 'b')"); //$NON-NLS-1$
}
- public void testSetCriteria4() {
+ @Test public void testSetCriteria4() {
SetCriteria sc = new SetCriteria();
sc.setExpression(new ElementSymbol("e1")); //$NON-NLS-1$
ArrayList values = new ArrayList();
@@ -772,7 +768,7 @@
helpTest(sc, "e1 NOT IN (e2, 'abc')"); //$NON-NLS-1$
}
- public void testSetQuery1() {
+ @Test public void testSetQuery1() {
Select s1 = new Select();
s1.addSymbol(new ElementSymbol("e1")); //$NON-NLS-1$
From f1 = new From();
@@ -794,7 +790,7 @@
helpTest(sq, "SELECT e1 FROM m.g1 UNION SELECT e1 FROM m.g2"); //$NON-NLS-1$
}
- public void testSetQuery2() {
+ @Test public void testSetQuery2() {
Select s1 = new Select();
s1.addSymbol(new ElementSymbol("e1")); //$NON-NLS-1$
From f1 = new From();
@@ -816,7 +812,7 @@
helpTest(sq, "SELECT e1 FROM m.g1 UNION ALL SELECT e1 FROM m.g2"); //$NON-NLS-1$
}
- public void testSetQuery3() {
+ @Test public void testSetQuery3() {
Select s1 = new Select();
s1.addSymbol(new ElementSymbol("e1")); //$NON-NLS-1$
From f1 = new From();
@@ -842,7 +838,7 @@
helpTest(sq, "SELECT e1 FROM m.g1 UNION SELECT e1 FROM m.g2 ORDER BY e1"); //$NON-NLS-1$
}
- public void testSetQuery4() {
+ @Test public void testSetQuery4() {
Select s1 = new Select();
s1.addSymbol(new ElementSymbol("e1")); //$NON-NLS-1$
From f1 = new From();
@@ -864,7 +860,7 @@
helpTest(sq, "SELECT e1 FROM m.g1 UNION SELECT e1 FROM m.g2"); //$NON-NLS-1$
}
- public void testSetQuery5() {
+ @Test public void testSetQuery5() {
Select s1 = new Select();
s1.addSymbol(new ElementSymbol("e1")); //$NON-NLS-1$
From f1 = new From();
@@ -896,7 +892,7 @@
helpTest(sq2, "SELECT e3 FROM m.g3 UNION ALL (SELECT e1 FROM m.g1 UNION SELECT e1 FROM m.g2)"); //$NON-NLS-1$
}
- public void testSubqueryFromClause1() {
+ @Test public void testSubqueryFromClause1() {
Select s1 = new Select();
s1.addSymbol(new ElementSymbol("e1")); //$NON-NLS-1$
From f1 = new From();
@@ -909,7 +905,7 @@
helpTest(sfc, "(SELECT e1 FROM m.g1) AS temp"); //$NON-NLS-1$
}
- public void testOptionalSubqueryFromClause1() {
+ @Test public void testOptionalSubqueryFromClause1() {
Select s1 = new Select();
s1.addSymbol(new ElementSymbol("e1")); //$NON-NLS-1$
From f1 = new From();
@@ -923,7 +919,7 @@
helpTest(sfc, "/*+ optional */ (SELECT e1 FROM m.g1) AS temp"); //$NON-NLS-1$
}
- public void testSubquerySetCriteria1() {
+ @Test public void testSubquerySetCriteria1() {
Select s1 = new Select();
s1.addSymbol(new ElementSymbol("e1")); //$NON-NLS-1$
From f1 = new From();
@@ -938,7 +934,7 @@
helpTest(ssc, "e2 IN (SELECT e1 FROM m.g1)"); //$NON-NLS-1$
}
- public void testSubquerySetCriteria2() {
+ @Test public void testSubquerySetCriteria2() {
Select s1 = new Select();
s1.addSymbol(new ElementSymbol("e1")); //$NON-NLS-1$
From f1 = new From();
@@ -954,17 +950,17 @@
helpTest(ssc, "e2 NOT IN (SELECT e1 FROM m.g1)"); //$NON-NLS-1$
}
- public void testUnaryFromClause() {
+ @Test public void testUnaryFromClause() {
helpTest(new UnaryFromClause(new GroupSymbol("m.g1")), "m.g1"); //$NON-NLS-1$ //$NON-NLS-2$
}
- public void testOptionalUnaryFromClause() {
+ @Test public void testOptionalUnaryFromClause() {
UnaryFromClause unaryFromClause = new UnaryFromClause(new GroupSymbol("m.g1"));//$NON-NLS-1$
unaryFromClause.setOptional(true);
helpTest(unaryFromClause, "/*+ optional */ m.g1"); //$NON-NLS-1$
}
- public void testUpdate1() {
+ @Test public void testUpdate1() {
Update update = new Update();
update.setGroup(new GroupSymbol("m.g1")); //$NON-NLS-1$
update.addChange(new ElementSymbol("e1"), new Constant("abc")); //$NON-NLS-1$ //$NON-NLS-2$
@@ -972,7 +968,7 @@
helpTest(update, "UPDATE m.g1 SET e1 = 'abc'"); //$NON-NLS-1$
}
- public void testUpdate2() {
+ @Test public void testUpdate2() {
Update update = new Update();
update.setGroup(new GroupSymbol("m.g1")); //$NON-NLS-1$
update.addChange(new ElementSymbol("e1"), new Constant("abc")); //$NON-NLS-1$ //$NON-NLS-2$
@@ -981,7 +977,7 @@
helpTest(update, "UPDATE m.g1 SET e1 = 'abc', e2 = 'xyz'"); //$NON-NLS-1$
}
- public void testUpdate3() {
+ @Test public void testUpdate3() {
Update update = new Update();
update.setGroup(new GroupSymbol("m.g1")); //$NON-NLS-1$
update.addChange(new ElementSymbol("e1"), new Constant("abc")); //$NON-NLS-1$ //$NON-NLS-2$
@@ -994,163 +990,163 @@
helpTest(update, "UPDATE m.g1 SET e1 = 'abc' WHERE e2 = 'abc'"); //$NON-NLS-1$
}
- public void testAggregateSymbol1() {
+ @Test public void testAggregateSymbol1() {
AggregateSymbol agg = new AggregateSymbol("abc", NonReserved.COUNT, false, new Constant("abc")); //$NON-NLS-1$ //$NON-NLS-2$
helpTest(agg, "COUNT('abc')"); //$NON-NLS-1$
}
- public void testAggregateSymbol2() {
+ @Test public void testAggregateSymbol2() {
AggregateSymbol agg = new AggregateSymbol("abc", NonReserved.COUNT, true, new Constant("abc")); //$NON-NLS-1$ //$NON-NLS-2$
helpTest(agg, "COUNT(DISTINCT 'abc')"); //$NON-NLS-1$
}
- public void testAggregateSymbol3() {
+ @Test public void testAggregateSymbol3() {
AggregateSymbol agg = new AggregateSymbol("abc", NonReserved.COUNT, false, null); //$NON-NLS-1$
helpTest(agg, "COUNT(*)"); //$NON-NLS-1$
}
- public void testAggregateSymbol4() {
+ @Test public void testAggregateSymbol4() {
AggregateSymbol agg = new AggregateSymbol("abc", NonReserved.AVG, false, new Constant("abc")); //$NON-NLS-1$ //$NON-NLS-2$
helpTest(agg, "AVG('abc')"); //$NON-NLS-1$
}
- public void testAggregateSymbol5() {
+ @Test public void testAggregateSymbol5() {
AggregateSymbol agg = new AggregateSymbol("abc", NonReserved.SUM, false, new Constant("abc")); //$NON-NLS-1$ //$NON-NLS-2$
helpTest(agg, "SUM('abc')"); //$NON-NLS-1$
}
- public void testAggregateSymbol6() {
+ @Test public void testAggregateSymbol6() {
AggregateSymbol agg = new AggregateSymbol("abc", NonReserved.MIN, false, new Constant("abc")); //$NON-NLS-1$ //$NON-NLS-2$
helpTest(agg, "MIN('abc')"); //$NON-NLS-1$
}
- public void testAggregateSymbol7() {
+ @Test public void testAggregateSymbol7() {
AggregateSymbol agg = new AggregateSymbol("abc", NonReserved.MAX, false, new Constant("abc")); //$NON-NLS-1$ //$NON-NLS-2$
helpTest(agg, "MAX('abc')"); //$NON-NLS-1$
}
- public void testAliasSymbol1() {
+ @Test public void testAliasSymbol1() {
AliasSymbol as = new AliasSymbol("x", new ElementSymbol("y")); //$NON-NLS-1$ //$NON-NLS-2$
helpTest(as, "y AS x"); //$NON-NLS-1$
}
// Test alias symbol with reserved word
- public void testAliasSymbol2() {
+ @Test public void testAliasSymbol2() {
AliasSymbol as = new AliasSymbol("select", new ElementSymbol("y")); //$NON-NLS-1$ //$NON-NLS-2$
helpTest(as, "y AS \"select\""); //$NON-NLS-1$
}
- public void testAllSymbol() {
+ @Test public void testAllSymbol() {
helpTest(new MultipleElementSymbol(), "*"); //$NON-NLS-1$
}
- public void testAllInGroupSymbol() {
+ @Test public void testAllInGroupSymbol() {
helpTest(new MultipleElementSymbol("m.g"), "m.g.*"); //$NON-NLS-1$ //$NON-NLS-2$
}
- public void testConstantNull() {
+ @Test public void testConstantNull() {
helpTest(new Constant(null), "null"); //$NON-NLS-1$
}
- public void testConstantString() {
+ @Test public void testConstantString() {
helpTest(new Constant("abc"), "'abc'"); //$NON-NLS-1$ //$NON-NLS-2$
}
- public void testConstantInteger() {
+ @Test public void testConstantInteger() {
helpTest(new Constant(new Integer(5)), "5"); //$NON-NLS-1$
}
- public void testConstantBigDecimal() {
+ @Test public void testConstantBigDecimal() {
helpTest(new Constant(new BigDecimal("5.4")), "5.4"); //$NON-NLS-1$ //$NON-NLS-2$
}
- public void testConstantStringWithTick() {
+ @Test public void testConstantStringWithTick() {
helpTest(new Constant("O'Leary"), "'O''Leary'"); //$NON-NLS-1$ //$NON-NLS-2$
}
- public void testConstantStringWithTicks() {
+ @Test public void testConstantStringWithTicks() {
helpTest(new Constant("'abc'"), "'''abc'''"); //$NON-NLS-1$ //$NON-NLS-2$
}
- public void testConstantStringWithMoreTicks() {
+ @Test public void testConstantStringWithMoreTicks() {
helpTest(new Constant("a'b'c"), "'a''b''c'"); //$NON-NLS-1$ //$NON-NLS-2$
}
- public void testConstantStringWithDoubleTick() {
+ @Test public void testConstantStringWithDoubleTick() {
helpTest(new Constant("group=\"x\""), "'group=\"x\"'"); //$NON-NLS-1$ //$NON-NLS-2$
}
- public void testConstantBooleanTrue() {
+ @Test public void testConstantBooleanTrue() {
helpTest(new Constant(Boolean.TRUE), "TRUE"); //$NON-NLS-1$
}
- public void testConstantBooleanFalse() {
+ @Test public void testConstantBooleanFalse() {
helpTest(new Constant(Boolean.FALSE), "FALSE"); //$NON-NLS-1$
}
- public void testConstantDate() {
+ @Test public void testConstantDate() {
helpTest(new Constant(java.sql.Date.valueOf("2002-10-02")), "{d'2002-10-02'}"); //$NON-NLS-1$ //$NON-NLS-2$
}
- public void testConstantTime() {
+ @Test public void testConstantTime() {
helpTest(new Constant(java.sql.Time.valueOf("5:00:00")), "{t'05:00:00'}"); //$NON-NLS-1$ //$NON-NLS-2$
}
- public void testConstantTimestamp() {
+ @Test public void testConstantTimestamp() {
helpTest(new Constant(java.sql.Timestamp.valueOf("2002-10-02 17:10:35.0234")), "{ts'2002-10-02 17:10:35.0234'}"); //$NON-NLS-1$ //$NON-NLS-2$
}
- public void testElementSymbol1() {
+ @Test public void testElementSymbol1() {
ElementSymbol es = new ElementSymbol("elem"); //$NON-NLS-1$
helpTest(es, "elem"); //$NON-NLS-1$
}
- public void testElementSymbol2() {
+ @Test public void testElementSymbol2() {
ElementSymbol es = new ElementSymbol("elem", false); //$NON-NLS-1$
es.setGroupSymbol(new GroupSymbol("m.g")); //$NON-NLS-1$
helpTest(es, "elem"); //$NON-NLS-1$
}
- public void testElementSymbol3() {
+ @Test public void testElementSymbol3() {
ElementSymbol es = new ElementSymbol("m.g.elem", true); //$NON-NLS-1$
es.setGroupSymbol(new GroupSymbol("m.g")); //$NON-NLS-1$
helpTest(es, "m.g.elem"); //$NON-NLS-1$
}
- public void testElementSymbol4() {
+ @Test public void testElementSymbol4() {
ElementSymbol es = new ElementSymbol("vdb.m.g.elem", true); //$NON-NLS-1$
helpTest(es, "vdb.m.g.elem"); //$NON-NLS-1$
}
- public void testElementSymbol5() {
+ @Test public void testElementSymbol5() {
ElementSymbol es = new ElementSymbol("m.g.select", false); //$NON-NLS-1$
es.setGroupSymbol(new GroupSymbol("m.g")); //$NON-NLS-1$
helpTest(es, "\"select\""); //$NON-NLS-1$
}
- public void testExpressionSymbol1() {
+ @Test public void testExpressionSymbol1() {
ExpressionSymbol expr = new ExpressionSymbol("abc", new Constant("abc")); //$NON-NLS-1$ //$NON-NLS-2$
helpTest(expr, "'abc'"); //$NON-NLS-1$
}
- public void testFunction1() {
+ @Test public void testFunction1() {
Function func = new Function("concat", new Expression[] { //$NON-NLS-1$
new Constant("a"), null //$NON-NLS-1$
});
helpTest(func, "concat('a', <undefined>)"); //$NON-NLS-1$
}
- public void testFunction2() {
+ @Test public void testFunction2() {
Function func = new Function("now", new Expression[] {}); //$NON-NLS-1$
helpTest(func, "now()"); //$NON-NLS-1$
}
- public void testFunction3() {
+ @Test public void testFunction3() {
Function func = new Function("concat", new Expression[] {null, null}); //$NON-NLS-1$
helpTest(func, "concat(<undefined>, <undefined>)"); //$NON-NLS-1$
}
- public void testFunction4() {
+ @Test public void testFunction4() {
Function func1 = new Function("power", new Expression[] { //$NON-NLS-1$
new Constant(new Integer(5)),
new Constant(new Integer(3)) });
@@ -1163,7 +1159,7 @@
helpTest(func3, "(1000 + power(power(5, 3), 3))"); //$NON-NLS-1$
}
- public void testFunction5() {
+ @Test public void testFunction5() {
Function func1 = new Function("concat", new Expression[] { //$NON-NLS-1$
new ElementSymbol("elem2"), //$NON-NLS-1$
null });
@@ -1173,7 +1169,7 @@
helpTest(func2, "concat(elem1, concat(elem2, <undefined>))"); //$NON-NLS-1$
}
- public void testConvertFunction1() {
+ @Test public void testConvertFunction1() {
Function func = new Function("convert", new Expression[] { //$NON-NLS-1$
new Constant("5"), //$NON-NLS-1$
new Constant("integer") //$NON-NLS-1$
@@ -1181,7 +1177,7 @@
helpTest(func, "convert('5', integer)"); //$NON-NLS-1$
}
- public void testConvertFunction2() {
+ @Test public void testConvertFunction2() {
Function func = new Function("convert", new Expression[] { //$NON-NLS-1$
null,
new Constant("integer") //$NON-NLS-1$
@@ -1189,7 +1185,7 @@
helpTest(func, "convert(<undefined>, integer)"); //$NON-NLS-1$
}
- public void testConvertFunction3() {
+ @Test public void testConvertFunction3() {
Function func = new Function("convert", new Expression[] { //$NON-NLS-1$
new Constant(null),
new Constant("integer") //$NON-NLS-1$
@@ -1197,7 +1193,7 @@
helpTest(func, "convert(null, integer)"); //$NON-NLS-1$
}
- public void testConvertFunction4() {
+ @Test public void testConvertFunction4() {
Function func = new Function("convert", new Expression[] { //$NON-NLS-1$
new Constant("abc"), //$NON-NLS-1$
null
@@ -1205,22 +1201,22 @@
helpTest(func, "convert('abc', <undefined>)"); //$NON-NLS-1$
}
- public void testConvertFunction5() {
+ @Test public void testConvertFunction5() {
Function func = new Function("convert", null); //$NON-NLS-1$
helpTest(func, "convert()"); //$NON-NLS-1$
}
- public void testConvertFunction6() {
+ @Test public void testConvertFunction6() {
Function func = new Function("convert", new Expression[0]); //$NON-NLS-1$
helpTest(func, "convert()"); //$NON-NLS-1$
}
- public void testConvertFunction7() {
+ @Test public void testConvertFunction7() {
Function func = new Function("convert", new Expression[] {new Constant("abc")}); //$NON-NLS-1$ //$NON-NLS-2$
helpTest(func, "convert('abc', <undefined>)"); //$NON-NLS-1$
}
- public void testCastFunction1() {
+ @Test public void testCastFunction1() {
Function func = new Function("cast", new Expression[] { //$NON-NLS-1$
new Constant("5"), //$NON-NLS-1$
new Constant("integer") //$NON-NLS-1$
@@ -1228,7 +1224,7 @@
helpTest(func, "cast('5' AS integer)"); //$NON-NLS-1$
}
- public void testCastFunction2() {
+ @Test public void testCastFunction2() {
Function func = new Function("cast", new Expression[] { //$NON-NLS-1$
null,
new Constant("integer") //$NON-NLS-1$
@@ -1236,7 +1232,7 @@
helpTest(func, "cast(<undefined> AS integer)"); //$NON-NLS-1$
}
- public void testCastFunction3() {
+ @Test public void testCastFunction3() {
Function func = new Function("cast", new Expression[] { //$NON-NLS-1$
new Constant(null),
new Constant("integer") //$NON-NLS-1$
@@ -1244,7 +1240,7 @@
helpTest(func, "cast(null AS integer)"); //$NON-NLS-1$
}
- public void testCastFunction4() {
+ @Test public void testCastFunction4() {
Function func = new Function("cast", new Expression[] { //$NON-NLS-1$
new Constant("abc"), //$NON-NLS-1$
null
@@ -1252,50 +1248,50 @@
helpTest(func, "cast('abc' AS <undefined>)"); //$NON-NLS-1$
}
- public void testArithemeticFunction1() {
+ @Test public void testArithemeticFunction1() {
Function func = new Function("-", new Expression[] { //$NON-NLS-1$
new Constant(new Integer(-2)),
new Constant(new Integer(-1))});
helpTest(func, "(-2 - -1)"); //$NON-NLS-1$
}
- public void testGroupSymbol1() {
+ @Test public void testGroupSymbol1() {
GroupSymbol gs = new GroupSymbol("g"); //$NON-NLS-1$
helpTest(gs, "g"); //$NON-NLS-1$
}
- public void testGroupSymbol2() {
+ @Test public void testGroupSymbol2() {
GroupSymbol gs = new GroupSymbol("x", "g"); //$NON-NLS-1$ //$NON-NLS-2$
helpTest(gs, "g AS x"); //$NON-NLS-1$
}
- public void testGroupSymbol3() {
+ @Test public void testGroupSymbol3() {
GroupSymbol gs = new GroupSymbol("vdb.g"); //$NON-NLS-1$
helpTest(gs, "vdb.g"); //$NON-NLS-1$
}
- public void testGroupSymbol4() {
+ @Test public void testGroupSymbol4() {
GroupSymbol gs = new GroupSymbol("x", "vdb.g"); //$NON-NLS-1$ //$NON-NLS-2$
helpTest(gs, "vdb.g AS x"); //$NON-NLS-1$
}
- public void testGroupSymbol5() {
+ @Test public void testGroupSymbol5() {
GroupSymbol gs = new GroupSymbol("from", "m.g"); //$NON-NLS-1$ //$NON-NLS-2$
helpTest(gs, "m.g AS \"from\""); //$NON-NLS-1$
}
- public void testGroupSymbol6() {
+ @Test public void testGroupSymbol6() {
GroupSymbol gs = new GroupSymbol("x", "on.select"); //$NON-NLS-1$ //$NON-NLS-2$
helpTest(gs, "\"on\".\"select\" AS x"); //$NON-NLS-1$
}
- public void testExecNoParams() {
+ @Test public void testExecNoParams() {
StoredProcedure proc = new StoredProcedure();
proc.setProcedureName("myproc"); //$NON-NLS-1$
helpTest(proc, "EXEC myproc()"); //$NON-NLS-1$
}
- public void testExecInputParam() {
+ @Test public void testExecInputParam() {
StoredProcedure proc = new StoredProcedure();
proc.setProcedureName("myproc"); //$NON-NLS-1$
SPParameter param = new SPParameter(1, new Reference(0));
@@ -1303,7 +1299,7 @@
helpTest(proc, "EXEC myproc(?)"); //$NON-NLS-1$
}
- public void testExecInputOutputParam() {
+ @Test public void testExecInputOutputParam() {
StoredProcedure proc = new StoredProcedure();
proc.setProcedureName("myproc"); //$NON-NLS-1$
SPParameter param1 = new SPParameter(1, new Constant(new Integer(5)));
@@ -1316,7 +1312,7 @@
helpTest(proc, "EXEC myproc(5)"); //$NON-NLS-1$
}
- public void testExecOutputInputParam() {
+ @Test public void testExecOutputInputParam() {
StoredProcedure proc = new StoredProcedure();
proc.setProcedureName("myproc"); //$NON-NLS-1$
@@ -1330,7 +1326,7 @@
helpTest(proc, "EXEC myproc(5)"); //$NON-NLS-1$
}
- public void testExecReturnParam() {
+ @Test public void testExecReturnParam() {
StoredProcedure proc = new StoredProcedure();
proc.setProcedureName("myproc"); //$NON-NLS-1$
@@ -1339,7 +1335,7 @@
helpTest(proc, "EXEC myproc()"); //$NON-NLS-1$
}
- public void testExecNamedParam() {
+ @Test public void testExecNamedParam() {
StoredProcedure proc = new StoredProcedure();
proc.setDisplayNamedParameters(true);
proc.setProcedureName("myproc"); //$NON-NLS-1$
@@ -1349,7 +1345,7 @@
helpTest(proc, "EXEC myproc(p1 => ?)"); //$NON-NLS-1$
}
- public void testExecNamedParams() {
+ @Test public void testExecNamedParams() {
StoredProcedure proc = new StoredProcedure();
proc.setDisplayNamedParameters(true);
proc.setProcedureName("myproc"); //$NON-NLS-1$
@@ -1369,7 +1365,7 @@
*
* @since 4.3
*/
- public void testExecNamedParamsReservedWord() {
+ @Test public void testExecNamedParamsReservedWord() {
StoredProcedure proc = new StoredProcedure();
proc.setDisplayNamedParameters(true);
proc.setProcedureName("myproc"); //$NON-NLS-1$
@@ -1384,27 +1380,27 @@
// Test methods for Update Procedure Language Objects
- public void testDeclareStatement() {
+ @Test public void testDeclareStatement() {
DeclareStatement dclStmt = new DeclareStatement(new ElementSymbol("a"), "String"); //$NON-NLS-1$ //$NON-NLS-2$
helpTest(dclStmt, "DECLARE String a;"); //$NON-NLS-1$
}
- public void testRaiseErrorStatement() {
+ @Test public void testRaiseErrorStatement() {
RaiseErrorStatement errStmt = new RaiseErrorStatement(new Constant("My Error")); //$NON-NLS-1$
helpTest(errStmt, "ERROR 'My Error';"); //$NON-NLS-1$
}
- public void testRaiseErrorStatementWithExpression() {
+ @Test public void testRaiseErrorStatementWithExpression() {
RaiseErrorStatement errStmt = new RaiseErrorStatement(new ElementSymbol("a")); //$NON-NLS-1$
helpTest(errStmt, "ERROR a;"); //$NON-NLS-1$
}
- public void testAssignmentStatement1() {
+ @Test public void testAssignmentStatement1() {
AssignmentStatement assigStmt = new AssignmentStatement(new ElementSymbol("a"), new Constant(new Integer(1))); //$NON-NLS-1$
helpTest(assigStmt, "a = 1;"); //$NON-NLS-1$
}
- public void testAssignmentStatement2() {
+ @Test public void testAssignmentStatement2() {
Query q1 = new Query();
Select select = new Select();
select.addSymbol(new ElementSymbol("x")); //$NON-NLS-1$
@@ -1417,7 +1413,7 @@
helpTest(assigStmt, "a = (SELECT x FROM g);"); //$NON-NLS-1$
}
- public void testCriteriaSelector1() {
+ @Test public void testCriteriaSelector1() {
ElementSymbol sy1 = new ElementSymbol("a"); //$NON-NLS-1$
ElementSymbol sy2 = new ElementSymbol("b"); //$NON-NLS-1$
ElementSymbol sy3 = new ElementSymbol("c"); //$NON-NLS-1$
@@ -1429,7 +1425,7 @@
helpTest(cs, "= CRITERIA ON (a, b, c)"); //$NON-NLS-1$
}
- public void testCriteriaSelector2() {
+ @Test public void testCriteriaSelector2() {
ElementSymbol sy1 = new ElementSymbol("x"); //$NON-NLS-1$
ElementSymbol sy2 = new ElementSymbol("y"); //$NON-NLS-1$
ElementSymbol sy3 = new ElementSymbol("z"); //$NON-NLS-1$
@@ -1441,7 +1437,7 @@
helpTest(cs, "LIKE CRITERIA ON (x, y, z)"); //$NON-NLS-1$
}
- public void testCriteriaSelector3() {
+ @Test public void testCriteriaSelector3() {
ElementSymbol sy1 = new ElementSymbol("x"); //$NON-NLS-1$
ElementSymbol sy2 = new ElementSymbol("y"); //$NON-NLS-1$
ElementSymbol sy3 = new ElementSymbol("z"); //$NON-NLS-1$
@@ -1453,7 +1449,7 @@
helpTest(cs, "BETWEEN CRITERIA ON (x, y, z)"); //$NON-NLS-1$
}
- public void testHasCriteria1() {
+ @Test public void testHasCriteria1() {
ElementSymbol sy1 = new ElementSymbol("x"); //$NON-NLS-1$
ElementSymbol sy2 = new ElementSymbol("y"); //$NON-NLS-1$
ElementSymbol sy3 = new ElementSymbol("z"); //$NON-NLS-1$
@@ -1465,7 +1461,7 @@
helpTest(new HasCriteria(cs), "HAS LIKE CRITERIA ON (x, y, z)"); //$NON-NLS-1$
}
- public void testHasCriteria2() {
+ @Test public void testHasCriteria2() {
ElementSymbol sy1 = new ElementSymbol("x"); //$NON-NLS-1$
ElementSymbol sy2 = new ElementSymbol("y"); //$NON-NLS-1$
ElementSymbol sy3 = new ElementSymbol("z"); //$NON-NLS-1$
@@ -1477,7 +1473,7 @@
helpTest(new HasCriteria(cs), "HAS LIKE CRITERIA ON (x, y, z)"); //$NON-NLS-1$
}
- public void testHasCriteria3() {
+ @Test public void testHasCriteria3() {
ElementSymbol sy1 = new ElementSymbol("x"); //$NON-NLS-1$
ElementSymbol sy2 = new ElementSymbol("y"); //$NON-NLS-1$
ElementSymbol sy3 = new ElementSymbol("z"); //$NON-NLS-1$
@@ -1489,7 +1485,7 @@
helpTest(new HasCriteria(cs), "HAS BETWEEN CRITERIA ON (x, y, z)"); //$NON-NLS-1$
}
- public void testCommandStatement1() {
+ @Test public void testCommandStatement1() {
Query q1 = new Query();
Select select = new Select();
select.addSymbol(new ElementSymbol("x")); //$NON-NLS-1$
@@ -1502,14 +1498,14 @@
helpTest(cmdStmt, "SELECT x FROM g;"); //$NON-NLS-1$
}
- public void testCommandStatement2() {
+ @Test public void testCommandStatement2() {
Delete d1 = new Delete();
d1.setGroup(new GroupSymbol("g")); //$NON-NLS-1$
CommandStatement cmdStmt = new CommandStatement(d1);
helpTest(cmdStmt, "DELETE FROM g;"); //$NON-NLS-1$
}
- public void testBlock1() {
+ @Test public void testBlock1() {
Delete d1 = new Delete();
d1.setGroup(new GroupSymbol("g")); //$NON-NLS-1$
CommandStatement cmdStmt = new CommandStatement(d1);
@@ -1522,7 +1518,7 @@
helpTest(b, "BEGIN\nDELETE FROM g;\na = 1;\nERROR 'My Error';\nEND"); //$NON-NLS-1$
}
- public void testBlock2() {
+ @Test public void testBlock2() {
// construct If statement
Delete d1 = new Delete();
@@ -1547,7 +1543,7 @@
helpTest(b, "BEGIN\nDELETE FROM g;\nIF(HAS LIKE CRITERIA ON (x))\nBEGIN\nDELETE FROM g;\nEND\nERROR 'My Error';\nEND"); //$NON-NLS-1$
}
- public void testIfStatement1() {
+ @Test public void testIfStatement1() {
// construct If block
Delete d1 = new Delete();
d1.setGroup(new GroupSymbol("g")); //$NON-NLS-1$
@@ -1570,7 +1566,7 @@
helpTest(ifStmt, "IF(HAS LIKE CRITERIA ON (x))\nBEGIN\nDELETE FROM g;\na = 1;\nERROR 'My Error';\nEND"); //$NON-NLS-1$
}
- public void testIfStatement2() {
+ @Test public void testIfStatement2() {
// construct If block
Delete d1 = new Delete();
d1.setGroup(new GroupSymbol("g")); //$NON-NLS-1$
@@ -1588,7 +1584,7 @@
helpTest(ifStmt, "IF(HAS LIKE CRITERIA ON (x))\nBEGIN\nDELETE FROM g;\nEND"); //$NON-NLS-1$
}
- public void testIfStatement3() {
+ @Test public void testIfStatement3() {
// construct If block
Delete d1 = new Delete();
d1.setGroup(new GroupSymbol("g")); //$NON-NLS-1$
@@ -1614,7 +1610,7 @@
helpTest(ifStmt, "IF(HAS LIKE CRITERIA ON (x))\nBEGIN\nDELETE FROM g;\na = 1;\nERROR 'My Error';\nEND\nELSE\nBEGIN\nDELETE FROM g;\nEND"); //$NON-NLS-1$
}
- public void testCreateUpdateProcedure1() {
+ @Test public void testCreateUpdateProcedure1() {
Delete d1 = new Delete();
d1.setGroup(new GroupSymbol("g")); //$NON-NLS-1$
CommandStatement cmdStmt = new CommandStatement(d1);
@@ -1628,7 +1624,7 @@
helpTest(cup, "CREATE PROCEDURE\nBEGIN\nDELETE FROM g;\na = 1;\nERROR 'My Error';\nEND"); //$NON-NLS-1$
}
- public void testCreateUpdateProcedure2() {
+ @Test public void testCreateUpdateProcedure2() {
Delete d1 = new Delete();
d1.setGroup(new GroupSymbol("g")); //$NON-NLS-1$
CommandStatement cmdStmt = new CommandStatement(d1);
@@ -1642,7 +1638,7 @@
helpTest(cup, "CREATE PROCEDURE\nBEGIN\nDELETE FROM g;\na = 1;\nERROR 'My Error';\nEND"); //$NON-NLS-1$
}
- public void testCreateUpdateProcedure3() {
+ @Test public void testCreateUpdateProcedure3() {
Delete d1 = new Delete();
d1.setGroup(new GroupSymbol("g")); //$NON-NLS-1$
CommandStatement cmdStmt = new CommandStatement(d1);
@@ -1656,7 +1652,7 @@
helpTest(cup, "CREATE PROCEDURE\nBEGIN\nDELETE FROM g;\na = 1;\nERROR 'My Error';\nEND"); //$NON-NLS-1$
}
- public void testSubqueryCompareCriteria1() {
+ @Test public void testSubqueryCompareCriteria1() {
Select s1 = new Select();
s1.addSymbol(new ElementSymbol("e1")); //$NON-NLS-1$
@@ -1673,7 +1669,7 @@
helpTest(scc, "e2 = ANY (SELECT e1 FROM m.g1)"); //$NON-NLS-1$
}
- public void testSubqueryCompareCriteria2() {
+ @Test public void testSubqueryCompareCriteria2() {
Select s1 = new Select();
s1.addSymbol(new ElementSymbol("e1")); //$NON-NLS-1$
@@ -1690,7 +1686,7 @@
helpTest(scc, "e2 <= SOME (SELECT e1 FROM m.g1)"); //$NON-NLS-1$
}
- public void testExistsCriteria1() {
+ @Test public void testExistsCriteria1() {
Select s1 = new Select();
s1.addSymbol(new ElementSymbol("e1")); //$NON-NLS-1$
@@ -1705,7 +1701,7 @@
helpTest(ec, "EXISTS (SELECT e1 FROM m.g1)"); //$NON-NLS-1$
}
- public void testDynamicCommand() {
+ @Test public void testDynamicCommand() {
List symbols = new ArrayList();
ElementSymbol a1 = new ElementSymbol("a1"); //$NON-NLS-1$
@@ -1723,7 +1719,7 @@
helpTest(obj, "EXECUTE 'SELECT a1 FROM g WHERE a2 = 5' AS a1 string INTO #g"); //$NON-NLS-1$
}
- public void testScalarSubquery() {
+ @Test public void testScalarSubquery() {
Select s1 = new Select();
s1.addSymbol(new ElementSymbol("e1")); //$NON-NLS-1$
@@ -1738,7 +1734,7 @@
helpTest(obj, "(SELECT e1 FROM m.g1)"); //$NON-NLS-1$
}
- public void testNewSubqueryObjects(){
+ @Test public void testNewSubqueryObjects(){
Select s1 = new Select();
s1.addSymbol(new ElementSymbol("e1")); //$NON-NLS-1$
@@ -1764,35 +1760,35 @@
helpTest(q2, "SELECT e1, (SELECT e1 FROM m.g1) FROM m.g2 WHERE (e3 >= ANY (SELECT e1 FROM m.g1)) AND (EXISTS (SELECT e1 FROM m.g1))"); //$NON-NLS-1$
}
- public void testCaseExpression1() {
+ @Test public void testCaseExpression1() {
helpTest(TestCaseExpression.example(2),
"CASE x WHEN 'a' THEN 0 WHEN 'b' THEN 1 ELSE 9999 END"); //$NON-NLS-1$
}
- public void testCaseExpression2() {
+ @Test public void testCaseExpression2() {
CaseExpression example = TestCaseExpression.example(2);
example.setElseExpression(null);
helpTest(example, "CASE x WHEN 'a' THEN 0 WHEN 'b' THEN 1 END"); //$NON-NLS-1$
}
- public void testCaseExpression3() {
+ @Test public void testCaseExpression3() {
CaseExpression example = TestCaseExpression.example(3, 0, true);
helpTest(example, "CASE x WHEN null THEN 0 WHEN 'b' THEN 1 WHEN 'c' THEN 2 ELSE 9999 END"); //$NON-NLS-1$
}
- public void testCaseExpression4() {
+ @Test public void testCaseExpression4() {
CaseExpression example = TestCaseExpression.example(3, 2, true);
example.setElseExpression(null);
helpTest(example, "CASE x WHEN 'a' THEN 0 WHEN 'b' THEN 1 WHEN null THEN 2 END"); //$NON-NLS-1$
}
- public void testSearchedCaseExpression1() {
+ @Test public void testSearchedCaseExpression1() {
helpTest(TestSearchedCaseExpression.example(2),
"CASE WHEN x = 0 THEN 0 WHEN x = 1 THEN 1 ELSE 9999 END"); //$NON-NLS-1$
}
- public void testSearchedCaseExpression2() {
+ @Test public void testSearchedCaseExpression2() {
SearchedCaseExpression example = TestSearchedCaseExpression.example(2);
example.setElseExpression(null);
helpTest(example,
@@ -1804,7 +1800,7 @@
* For some reason this test was outputting
* SELECT 'A' AS FOO UNION SELECT 'A' AS FOO
*/
- public void testSetQueryUnionOfLiteralsCase3102() {
+ @Test public void testSetQueryUnionOfLiteralsCase3102() {
String expected = "SELECT 'A' AS FOO UNION SELECT 'B' AS FOO"; //$NON-NLS-1$
@@ -1829,7 +1825,7 @@
* Same as above except that ExpressionSymbols' internal names (which aren't visible
* in the query) are different
*/
- public void testSetQueryUnionOfLiteralsCase3102a() {
+ @Test public void testSetQueryUnionOfLiteralsCase3102a() {
String expected = "SELECT 'A' AS FOO UNION SELECT 'B' AS FOO"; //$NON-NLS-1$
@@ -1848,7 +1844,7 @@
helpTest(sq, expected);
}
- public void testLimit() {
+ @Test public void testLimit() {
Query query = new Query();
Select select = new Select(Arrays.asList(new MultipleElementSymbol()));
From from = new From(Arrays.asList(new UnaryFromClause(new GroupSymbol("a")))); //$NON-NLS-1$
@@ -1858,7 +1854,7 @@
helpTest(query, "SELECT * FROM a LIMIT 100"); //$NON-NLS-1$
}
- public void testLimitWithOffset() {
+ @Test public void testLimitWithOffset() {
Query query = new Query();
Select select = new Select(Arrays.asList(new MultipleElementSymbol()));
From from = new From(Arrays.asList(new UnaryFromClause(new GroupSymbol("a")))); //$NON-NLS-1$
@@ -1868,28 +1864,42 @@
helpTest(query, "SELECT * FROM a LIMIT 50, 100"); //$NON-NLS-1$
}
- public void testUnionOrderBy() throws Exception {
+ @Test public void testUnionOrderBy() throws Exception {
Command command = QueryParser.getQueryParser().parseCommand("select pm1.g1.e1 from pm1.g1 union select e2 from pm1.g2 order by e1"); //$NON-NLS-1$
QueryResolver.resolveCommand(command, RealMetadataFactory.example1Cached());
helpTest(command, "SELECT pm1.g1.e1 FROM pm1.g1 UNION SELECT e2 FROM pm1.g2 ORDER BY e1"); //$NON-NLS-1$
}
- public void testUnionBranchOrderBy() throws Exception {
+ @Test public void testUnionBranchOrderBy() throws Exception {
Command command = QueryParser.getQueryParser().parseCommand("select pm1.g1.e1 from pm1.g1 union (select e2 from pm1.g2 order by e1)"); //$NON-NLS-1$
QueryResolver.resolveCommand(command, RealMetadataFactory.example1Cached());
helpTest(command, "SELECT pm1.g1.e1 FROM pm1.g1 UNION (SELECT e2 FROM pm1.g2 ORDER BY e1)"); //$NON-NLS-1$
}
- public void testAliasedOrderBy() throws Exception {
+ @Test public void testAliasedOrderBy() throws Exception {
Command command = QueryParser.getQueryParser().parseCommand("select pm1.g1.e1 as a from pm1.g1 order by a"); //$NON-NLS-1$
QueryResolver.resolveCommand(command, RealMetadataFactory.example1Cached());
helpTest(command, "SELECT pm1.g1.e1 AS a FROM pm1.g1 ORDER BY a"); //$NON-NLS-1$
}
- public void testNumberOrderBy() throws Exception {
+ @Test public void testNumberOrderBy() throws Exception {
Command command = QueryParser.getQueryParser().parseCommand("select pm1.g1.e1 as a from pm1.g1 order by 1"); //$NON-NLS-1$
QueryResolver.resolveCommand(command, RealMetadataFactory.example1Cached());
helpTest(command, "SELECT pm1.g1.e1 AS a FROM pm1.g1 ORDER BY 1"); //$NON-NLS-1$
}
+
+ public Expression helpTestExpression(String sql, String expected) throws QueryParserException {
+ Expression expr = QueryParser.getQueryParser().parseExpression(sql);
+ helpTest(expr, expected);
+ return expr;
+ }
+
+ @Test public void testLikeRegex() throws Exception {
+ helpTestExpression("x like_regex 'b'", "x LIKE_REGEX 'b'");
+ }
+
+ @Test public void testSimilar() throws Exception {
+ helpTestExpression("x similar to 'b' escape 'c'", "x SIMILAR TO 'b' ESCAPE 'c'");
+ }
}
14 years, 8 months
teiid SVN: r3363 - in branches/7.4.x/engine/src: test/java/org/teiid/query/processor/eval and 1 other directory.
by teiid-commits@lists.jboss.org
Author: shawkins
Date: 2011-08-04 13:51:11 -0400 (Thu, 04 Aug 2011)
New Revision: 3363
Modified:
branches/7.4.x/engine/src/main/java/org/teiid/query/eval/Evaluator.java
branches/7.4.x/engine/src/test/java/org/teiid/query/processor/eval/TestExpressionEvaluator.java
Log:
TEIID-1698 fix for + like matching
Modified: branches/7.4.x/engine/src/main/java/org/teiid/query/eval/Evaluator.java
===================================================================
--- branches/7.4.x/engine/src/main/java/org/teiid/query/eval/Evaluator.java 2011-08-04 17:08:29 UTC (rev 3362)
+++ branches/7.4.x/engine/src/main/java/org/teiid/query/eval/Evaluator.java 2011-08-04 17:51:11 UTC (rev 3363)
@@ -204,7 +204,7 @@
}
}
- private final static char[] REGEX_RESERVED = new char[] {'$', '(', ')', '*', '.', '?', '[', '\\', ']', '^', '{', '|', '}'}; //in sorted order
+ private final static char[] REGEX_RESERVED = new char[] {'$', '(', ')', '*', '+', '.', '?', '[', '\\', ']', '^', '{', '|', '}'}; //in sorted order
private final static MatchCriteria.PatternTranslator LIKE_TO_REGEX = new MatchCriteria.PatternTranslator(".*", ".", REGEX_RESERVED, '\\'); //$NON-NLS-1$ //$NON-NLS-2$
private Map elements;
Modified: branches/7.4.x/engine/src/test/java/org/teiid/query/processor/eval/TestExpressionEvaluator.java
===================================================================
--- branches/7.4.x/engine/src/test/java/org/teiid/query/processor/eval/TestExpressionEvaluator.java 2011-08-04 17:08:29 UTC (rev 3362)
+++ branches/7.4.x/engine/src/test/java/org/teiid/query/processor/eval/TestExpressionEvaluator.java 2011-08-04 17:51:11 UTC (rev 3363)
@@ -432,4 +432,9 @@
assertEquals(Boolean.TRUE, Evaluator.evaluate(inc));
}
+ @Test public void testLikePlus() throws Exception {
+ Expression ex = TestFunctionResolving.getExpression("'+' like '+'");
+ assertEquals(Boolean.TRUE, Evaluator.evaluate(ex));
+ }
+
}
14 years, 8 months
teiid SVN: r3362 - in branches/7.4.x/engine/src/main/java/org/teiid/query: xquery/saxon and 1 other directory.
by teiid-commits@lists.jboss.org
Author: shawkins
Date: 2011-08-04 13:08:29 -0400 (Thu, 04 Aug 2011)
New Revision: 3362
Added:
branches/7.4.x/engine/src/main/java/org/teiid/query/xquery/saxon/XQueryEvaluator.java
Modified:
branches/7.4.x/engine/src/main/java/org/teiid/query/eval/Evaluator.java
branches/7.4.x/engine/src/main/java/org/teiid/query/xquery/saxon/SaxonXQueryExpression.java
branches/7.4.x/engine/src/main/java/org/teiid/query/xquery/saxon/StreamingUtils.java
Log:
TEIID-1695 isolating xom/nux so that designer doesn't need the dependencies.
Modified: branches/7.4.x/engine/src/main/java/org/teiid/query/eval/Evaluator.java
===================================================================
--- branches/7.4.x/engine/src/main/java/org/teiid/query/eval/Evaluator.java 2011-08-04 15:31:44 UTC (rev 3361)
+++ branches/7.4.x/engine/src/main/java/org/teiid/query/eval/Evaluator.java 2011-08-04 17:08:29 UTC (rev 3362)
@@ -118,6 +118,7 @@
import org.teiid.query.sql.util.VariableContext;
import org.teiid.query.util.CommandContext;
import org.teiid.query.xquery.saxon.SaxonXQueryExpression;
+import org.teiid.query.xquery.saxon.XQueryEvaluator;
import org.teiid.query.xquery.saxon.SaxonXQueryExpression.Result;
import org.teiid.query.xquery.saxon.SaxonXQueryExpression.RowProcessor;
import org.teiid.translator.WSConnection.Util;
@@ -923,7 +924,7 @@
parameters.put(passing.getAlias(), value);
}
}
- return xquery.evaluateXQuery(contextItem, parameters, processor, context);
+ return XQueryEvaluator.evaluateXQuery(xquery, contextItem, parameters, processor, context);
}
private Evaluator.NameValuePair<Object>[] getNameValuePairs(List<?> tuple, List<DerivedColumn> args, boolean xmlNames)
Modified: branches/7.4.x/engine/src/main/java/org/teiid/query/xquery/saxon/SaxonXQueryExpression.java
===================================================================
--- branches/7.4.x/engine/src/main/java/org/teiid/query/xquery/saxon/SaxonXQueryExpression.java 2011-08-04 15:31:44 UTC (rev 3361)
+++ branches/7.4.x/engine/src/main/java/org/teiid/query/xquery/saxon/SaxonXQueryExpression.java 2011-08-04 17:08:29 UTC (rev 3362)
@@ -23,9 +23,7 @@
package org.teiid.query.xquery.saxon;
import java.io.IOException;
-import java.io.InputStream;
import java.io.Writer;
-import java.sql.SQLXML;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
@@ -40,9 +38,7 @@
import javax.xml.transform.Source;
import javax.xml.transform.TransformerException;
-import net.sf.saxon.AugmentedSource;
import net.sf.saxon.Configuration;
-import net.sf.saxon.event.ProxyReceiver;
import net.sf.saxon.expr.AxisExpression;
import net.sf.saxon.expr.ContextItemExpression;
import net.sf.saxon.expr.Expression;
@@ -53,14 +49,12 @@
import net.sf.saxon.expr.PathMap.PathMapNodeSet;
import net.sf.saxon.expr.PathMap.PathMapRoot;
import net.sf.saxon.om.Axis;
-import net.sf.saxon.om.DocumentInfo;
import net.sf.saxon.om.Item;
import net.sf.saxon.om.NodeInfo;
import net.sf.saxon.om.SequenceIterator;
import net.sf.saxon.om.StructuredQName;
import net.sf.saxon.pattern.AnyNodeTest;
import net.sf.saxon.pattern.NodeKindTest;
-import net.sf.saxon.query.DynamicQueryContext;
import net.sf.saxon.query.QueryResult;
import net.sf.saxon.query.StaticQueryContext;
import net.sf.saxon.query.XQueryExpression;
@@ -72,12 +66,6 @@
import net.sf.saxon.type.ItemType;
import net.sf.saxon.type.TypeHierarchy;
import net.sf.saxon.value.SequenceType;
-import nu.xom.Builder;
-import nu.xom.Element;
-import nu.xom.Nodes;
-import nu.xom.ParsingException;
-import nux.xom.xquery.StreamingPathFilter;
-import nux.xom.xquery.StreamingTransform;
import org.teiid.api.exception.query.QueryResolverException;
import org.teiid.common.buffer.BufferManager;
@@ -89,9 +77,6 @@
import org.teiid.core.types.XMLTranslator;
import org.teiid.core.types.XMLType;
import org.teiid.core.types.XMLType.Type;
-import org.teiid.logging.LogConstants;
-import org.teiid.logging.LogManager;
-import org.teiid.logging.MessageLevel;
import org.teiid.query.QueryPlugin;
import org.teiid.query.analysis.AnalysisRecord;
import org.teiid.query.function.source.XMLSystemFunctions;
@@ -100,7 +85,6 @@
import org.teiid.query.sql.symbol.DerivedColumn;
import org.teiid.query.sql.symbol.XMLNamespaces;
import org.teiid.query.sql.symbol.XMLNamespaces.NamespaceItem;
-import org.teiid.query.util.CommandContext;
import org.teiid.translator.WSConnection.Util;
@SuppressWarnings("serial")
@@ -113,15 +97,6 @@
DEFAULT_OUTPUT_PROPERTIES.setProperty(OutputKeys.OMIT_XML_DECLARATION, "yes"); //$NON-NLS-1$
}
- private static Nodes NONE = new Nodes();
- private static InputStream FAKE_IS = new InputStream() {
-
- @Override
- public int read() throws IOException {
- return 0;
- }
- };
-
public interface RowProcessor {
void processRow(NodeInfo row);
@@ -182,12 +157,12 @@
}
};
- private XQueryExpression xQuery;
- private String xQueryString;
- private Map<String, String> namespaceMap = new HashMap<String, String>();
- private Configuration config = new Configuration();
- private PathMapRoot contextRoot;
- private StreamingPathFilter streamingPathFilter;
+ XQueryExpression xQuery;
+ String xQueryString;
+ Map<String, String> namespaceMap = new HashMap<String, String>();
+ Configuration config = new Configuration();
+ PathMapRoot contextRoot;
+ String streamingPath;
public SaxonXQueryExpression(String xQueryString, XMLNamespaces namespaces, List<DerivedColumn> passing, List<XMLTable.XMLColumn> columns)
throws QueryResolverException {
@@ -246,7 +221,7 @@
clone.config = config;
clone.contextRoot = contextRoot;
clone.namespaceMap = namespaceMap;
- clone.streamingPathFilter = streamingPathFilter;
+ clone.streamingPath = streamingPath;
return clone;
}
@@ -256,7 +231,7 @@
public void useDocumentProjection(List<XMLTable.XMLColumn> columns, AnalysisRecord record) {
try {
- streamingPathFilter = StreamingUtils.getStreamingPathFilter(xQueryString, namespaceMap);
+ streamingPath = StreamingUtils.getStreamingPath(xQueryString, namespaceMap);
} catch (IllegalArgumentException e) {
if (record.recordDebug()) {
record.println("Document streaming will not be used: " + e.getMessage()); //$NON-NLS-1$
@@ -362,8 +337,8 @@
continue;
}
for (PathMapArc arc : subContextRoot.getArcs()) {
- if (streamingPathFilter != null && !validateColumnForStreaming(record, xmlColumn, arc)) {
- streamingPathFilter = null;
+ if (streamingPath != null && !validateColumnForStreaming(record, xmlColumn, arc)) {
+ streamingPath = null;
}
finalNode.createArc(arc.getStep(), arc.getTarget());
}
@@ -491,90 +466,7 @@
}
}
- public Result evaluateXQuery(Object context, Map<String, Object> parameterValues, final RowProcessor processor, CommandContext commandContext) throws TeiidProcessingException {
- DynamicQueryContext dynamicContext = new DynamicQueryContext(config);
-
- Result result = new Result();
- try {
- try {
- for (Map.Entry<String, Object> entry : parameterValues.entrySet()) {
- Object value = entry.getValue();
- if(value instanceof SQLXML) {
- value = XMLSystemFunctions.convertToSource(value);
- result.sources.add((Source)value);
- } else if (value instanceof java.util.Date) {
- value = XMLSystemFunctions.convertToAtomicValue(value);
- }
- dynamicContext.setParameter(entry.getKey(), value);
- }
- } catch (TransformerException e) {
- throw new TeiidProcessingException(e);
- }
- if (context != null) {
- Source source = XMLSystemFunctions.convertToSource(context);
- result.sources.add(source);
- if (contextRoot != null) {
- //create our own filter as this logic is not provided in the free saxon
- ProxyReceiver filter = new PathMapFilter(contextRoot);
- AugmentedSource sourceInput = AugmentedSource.makeAugmentedSource(source);
- sourceInput.addFilter(filter);
- source = sourceInput;
-
- //use streamable processing instead
- if (streamingPathFilter != null && processor != null) {
- if (LogManager.isMessageToBeRecorded(LogConstants.CTX_DQP, MessageLevel.DETAIL)) {
- LogManager.logDetail(LogConstants.CTX_DQP, "Using stream processing for evaluation of", this.xQueryString); //$NON-NLS-1$
- }
- //set to non-blocking in case default expression evaluation blocks
- boolean isNonBlocking = commandContext.isNonBlocking();
- commandContext.setNonBlocking(true);
-
- final StreamingTransform myTransform = new StreamingTransform() {
- public Nodes transform(Element elem) {
- processor.processRow(StreamingUtils.wrap(elem, config));
- return NONE;
- }
- };
-
- Builder builder = new Builder(new SaxonReader(config, sourceInput), false,
- streamingPathFilter.createNodeFactory(null, myTransform));
- try {
- //the builder is hard wired to parse the source, but the api will throw an exception if the stream is null
- builder.build(FAKE_IS);
- return result;
- } catch (ParsingException e) {
- throw new TeiidProcessingException(e, QueryPlugin.Util.getString("SaxonXQueryExpression.bad_context")); //$NON-NLS-1$
- } catch (IOException e) {
- throw new TeiidProcessingException(e, QueryPlugin.Util.getString("SaxonXQueryExpression.bad_context")); //$NON-NLS-1$
- } finally {
- if (!isNonBlocking) {
- commandContext.setNonBlocking(false);
- }
- }
- }
- }
- DocumentInfo doc;
- try {
- doc = config.buildDocument(source);
- } catch (XPathException e) {
- throw new TeiidProcessingException(e, QueryPlugin.Util.getString("SaxonXQueryExpression.bad_context")); //$NON-NLS-1$
- }
- dynamicContext.setContextItem(doc);
- }
- try {
- result.iter = xQuery.iterator(dynamicContext);
- return result;
- } catch (TransformerException e) {
- throw new TeiidProcessingException(e, QueryPlugin.Util.getString("SaxonXQueryExpression.bad_xquery")); //$NON-NLS-1$
- }
- } finally {
- if (result.iter == null) {
- result.close();
- }
- }
- }
-
- public XMLType createXMLType(final SequenceIterator iter, BufferManager bufferManager, boolean emptyOnEmpty) throws XPathException, TeiidComponentException, TeiidProcessingException {
+ public XMLType createXMLType(final SequenceIterator iter, BufferManager bufferManager, boolean emptyOnEmpty) throws XPathException, TeiidComponentException, TeiidProcessingException {
Item item = iter.next();
if (item == null && !emptyOnEmpty) {
return null;
@@ -634,7 +526,7 @@
}
public boolean isStreaming() {
- return streamingPathFilter != null;
+ return streamingPath != null;
}
}
Modified: branches/7.4.x/engine/src/main/java/org/teiid/query/xquery/saxon/StreamingUtils.java
===================================================================
--- branches/7.4.x/engine/src/main/java/org/teiid/query/xquery/saxon/StreamingUtils.java 2011-08-04 15:31:44 UTC (rev 3361)
+++ branches/7.4.x/engine/src/main/java/org/teiid/query/xquery/saxon/StreamingUtils.java 2011-08-04 17:08:29 UTC (rev 3362)
@@ -32,11 +32,7 @@
import net.sf.saxon.event.ProxyReceiver;
import net.sf.saxon.event.Receiver;
import net.sf.saxon.om.Name11Checker;
-import net.sf.saxon.om.NodeInfo;
import net.sf.saxon.trans.XPathException;
-import nu.xom.DocType;
-import nu.xom.Node;
-import nux.xom.xquery.StreamingPathFilter;
import org.xml.sax.ContentHandler;
import org.xml.sax.DTDHandler;
@@ -51,28 +47,6 @@
final class StreamingUtils {
/**
- * Converts a xom node into something readable by Saxon
- * @param node
- * @param config
- * @return
- */
- static NodeInfo wrap(Node node, Configuration config) {
- if (node == null)
- throw new IllegalArgumentException("node must not be null"); //$NON-NLS-1$
- if (node instanceof DocType)
- throw new IllegalArgumentException("DocType can't be queried by XQuery/XPath"); //$NON-NLS-1$
-
- Node root = node;
- while (root.getParent() != null) {
- root = root.getParent();
- }
-
- DocumentWrapper docWrapper = new DocumentWrapper(root, root.getBaseURI(), config);
-
- return docWrapper.wrap(node);
- }
-
- /**
* Pre-parser that adds validation and handles a default name space
*
* TODO: add support for more general paths including node tests
@@ -83,7 +57,7 @@
* @param prefixMap
* @return
*/
- public static StreamingPathFilter getStreamingPathFilter(String locationPath, Map<String, String> prefixMap) {
+ public static String getStreamingPath(String locationPath, Map<String, String> prefixMap) {
if (locationPath.indexOf("//") >= 0) //$NON-NLS-1$
throw new IllegalArgumentException("DESCENDANT axis is not supported"); //$NON-NLS-1$
@@ -124,7 +98,7 @@
}
fixedPath += localNames[i];
}
- return new StreamingPathFilter(fixedPath, prefixMap);
+ return fixedPath;
}
}
Added: branches/7.4.x/engine/src/main/java/org/teiid/query/xquery/saxon/XQueryEvaluator.java
===================================================================
--- branches/7.4.x/engine/src/main/java/org/teiid/query/xquery/saxon/XQueryEvaluator.java (rev 0)
+++ branches/7.4.x/engine/src/main/java/org/teiid/query/xquery/saxon/XQueryEvaluator.java 2011-08-04 17:08:29 UTC (rev 3362)
@@ -0,0 +1,177 @@
+/*
+ * 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.xquery.saxon;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.sql.SQLXML;
+import java.util.Map;
+
+import javax.xml.transform.Source;
+import javax.xml.transform.TransformerException;
+
+import net.sf.saxon.AugmentedSource;
+import net.sf.saxon.Configuration;
+import net.sf.saxon.event.ProxyReceiver;
+import net.sf.saxon.om.DocumentInfo;
+import net.sf.saxon.om.NodeInfo;
+import net.sf.saxon.query.DynamicQueryContext;
+import net.sf.saxon.trans.XPathException;
+import nu.xom.Builder;
+import nu.xom.DocType;
+import nu.xom.Element;
+import nu.xom.Node;
+import nu.xom.Nodes;
+import nu.xom.ParsingException;
+import nux.xom.xquery.StreamingPathFilter;
+import nux.xom.xquery.StreamingTransform;
+
+import org.teiid.core.TeiidProcessingException;
+import org.teiid.logging.LogConstants;
+import org.teiid.logging.LogManager;
+import org.teiid.logging.MessageLevel;
+import org.teiid.query.QueryPlugin;
+import org.teiid.query.function.source.XMLSystemFunctions;
+import org.teiid.query.util.CommandContext;
+import org.teiid.query.xquery.saxon.SaxonXQueryExpression.RowProcessor;
+
+/**
+ * Used to isolate the xom/nux dependency and to better isolate the saxon processing logic.
+ */
+public class XQueryEvaluator {
+
+ private static Nodes NONE = new Nodes();
+ private static InputStream FAKE_IS = new InputStream() {
+
+ @Override
+ public int read() throws IOException {
+ return 0;
+ }
+ };
+
+ public static SaxonXQueryExpression.Result evaluateXQuery(final SaxonXQueryExpression xquery, Object context, Map<String, Object> parameterValues, final RowProcessor processor, CommandContext commandContext) throws TeiidProcessingException {
+ DynamicQueryContext dynamicContext = new DynamicQueryContext(xquery.config);
+
+ SaxonXQueryExpression.Result result = new SaxonXQueryExpression.Result();
+ try {
+ try {
+ for (Map.Entry<String, Object> entry : parameterValues.entrySet()) {
+ Object value = entry.getValue();
+ if(value instanceof SQLXML) {
+ value = XMLSystemFunctions.convertToSource(value);
+ result.sources.add((Source)value);
+ } else if (value instanceof java.util.Date) {
+ value = XMLSystemFunctions.convertToAtomicValue(value);
+ }
+ dynamicContext.setParameter(entry.getKey(), value);
+ }
+ } catch (TransformerException e) {
+ throw new TeiidProcessingException(e);
+ }
+ if (context != null) {
+ Source source = XMLSystemFunctions.convertToSource(context);
+ result.sources.add(source);
+ if (xquery.contextRoot != null) {
+ //create our own filter as this logic is not provided in the free saxon
+ ProxyReceiver filter = new PathMapFilter(xquery.contextRoot);
+ AugmentedSource sourceInput = AugmentedSource.makeAugmentedSource(source);
+ sourceInput.addFilter(filter);
+ source = sourceInput;
+
+ //use streamable processing instead
+ if (xquery.streamingPath != null && processor != null) {
+ if (LogManager.isMessageToBeRecorded(LogConstants.CTX_DQP, MessageLevel.DETAIL)) {
+ LogManager.logDetail(LogConstants.CTX_DQP, "Using stream processing for evaluation of", xquery.xQueryString); //$NON-NLS-1$
+ }
+ //set to non-blocking in case default expression evaluation blocks
+ boolean isNonBlocking = commandContext.isNonBlocking();
+ commandContext.setNonBlocking(true);
+
+ final StreamingTransform myTransform = new StreamingTransform() {
+ public Nodes transform(Element elem) {
+ processor.processRow(XQueryEvaluator.wrap(elem, xquery.config));
+ return NONE;
+ }
+ };
+
+ Builder builder = new Builder(new SaxonReader(xquery.config, sourceInput), false,
+ new StreamingPathFilter(xquery.streamingPath, xquery.namespaceMap).createNodeFactory(null, myTransform));
+ try {
+ //the builder is hard wired to parse the source, but the api will throw an exception if the stream is null
+ builder.build(FAKE_IS);
+ return result;
+ } catch (ParsingException e) {
+ throw new TeiidProcessingException(e, QueryPlugin.Util.getString("SaxonXQueryExpression.bad_context")); //$NON-NLS-1$
+ } catch (IOException e) {
+ throw new TeiidProcessingException(e, QueryPlugin.Util.getString("SaxonXQueryExpression.bad_context")); //$NON-NLS-1$
+ } finally {
+ if (!isNonBlocking) {
+ commandContext.setNonBlocking(false);
+ }
+ }
+ }
+ }
+ DocumentInfo doc;
+ try {
+ doc = xquery.config.buildDocument(source);
+ } catch (XPathException e) {
+ throw new TeiidProcessingException(e, QueryPlugin.Util.getString("SaxonXQueryExpression.bad_context")); //$NON-NLS-1$
+ }
+ dynamicContext.setContextItem(doc);
+ }
+ try {
+ result.iter = xquery.xQuery.iterator(dynamicContext);
+ return result;
+ } catch (TransformerException e) {
+ throw new TeiidProcessingException(e, QueryPlugin.Util.getString("SaxonXQueryExpression.bad_xquery")); //$NON-NLS-1$
+ }
+ } finally {
+ if (result.iter == null) {
+ result.close();
+ }
+ }
+ }
+
+ /**
+ * Converts a xom node into something readable by Saxon
+ * @param node
+ * @param config
+ * @return
+ */
+ static NodeInfo wrap(Node node, Configuration config) {
+ if (node == null)
+ throw new IllegalArgumentException("node must not be null"); //$NON-NLS-1$
+ if (node instanceof DocType)
+ throw new IllegalArgumentException("DocType can't be queried by XQuery/XPath"); //$NON-NLS-1$
+
+ Node root = node;
+ while (root.getParent() != null) {
+ root = root.getParent();
+ }
+
+ DocumentWrapper docWrapper = new DocumentWrapper(root, root.getBaseURI(), config);
+
+ return docWrapper.wrap(node);
+ }
+
+}
Property changes on: branches/7.4.x/engine/src/main/java/org/teiid/query/xquery/saxon/XQueryEvaluator.java
___________________________________________________________________
Added: svn:mime-type
+ text/plain
14 years, 8 months
teiid SVN: r3361 - in branches/7.4.x: engine/src/main/java/org/teiid/dqp/internal/process and 1 other directories.
by teiid-commits@lists.jboss.org
Author: shawkins
Date: 2011-08-04 11:31:44 -0400 (Thu, 04 Aug 2011)
New Revision: 3361
Modified:
branches/7.4.x/client/src/main/java/org/teiid/jdbc/StatementImpl.java
branches/7.4.x/engine/src/main/java/org/teiid/dqp/internal/process/CachedResults.java
branches/7.4.x/engine/src/main/java/org/teiid/dqp/internal/process/RequestWorkItem.java
branches/7.4.x/engine/src/main/java/org/teiid/query/analysis/AnalysisRecord.java
Log:
TEIID-1697 no longer associating the analysisrecord with cached results
Modified: branches/7.4.x/client/src/main/java/org/teiid/jdbc/StatementImpl.java
===================================================================
--- branches/7.4.x/client/src/main/java/org/teiid/jdbc/StatementImpl.java 2011-08-04 15:04:00 UTC (rev 3360)
+++ branches/7.4.x/client/src/main/java/org/teiid/jdbc/StatementImpl.java 2011-08-04 15:31:44 UTC (rev 3361)
@@ -1060,9 +1060,15 @@
}
protected void setAnalysisInfo(ResultsMessage resultsMsg) {
- this.debugLog = resultsMsg.getDebugLog();
- this.currentPlanDescription = resultsMsg.getPlanDescription();
- this.annotations = resultsMsg.getAnnotations();
+ if (resultsMsg.getDebugLog() != null) {
+ this.debugLog = resultsMsg.getDebugLog();
+ }
+ if (resultsMsg.getPlanDescription() != null) {
+ this.currentPlanDescription = resultsMsg.getPlanDescription();
+ }
+ if (resultsMsg.getAnnotations() != null) {
+ this.annotations = resultsMsg.getAnnotations();
+ }
this.driverConnection.setDebugLog(debugLog);
this.driverConnection.setCurrentPlanDescription(currentPlanDescription);
this.driverConnection.setAnnotations(annotations);
Modified: branches/7.4.x/engine/src/main/java/org/teiid/dqp/internal/process/CachedResults.java
===================================================================
--- branches/7.4.x/engine/src/main/java/org/teiid/dqp/internal/process/CachedResults.java 2011-08-04 15:04:00 UTC (rev 3360)
+++ branches/7.4.x/engine/src/main/java/org/teiid/dqp/internal/process/CachedResults.java 2011-08-04 15:31:44 UTC (rev 3361)
@@ -41,7 +41,6 @@
import org.teiid.logging.LogConstants;
import org.teiid.logging.LogManager;
import org.teiid.query.QueryPlugin;
-import org.teiid.query.analysis.AnalysisRecord;
import org.teiid.query.metadata.QueryMetadataInterface;
import org.teiid.query.parser.ParseInfo;
import org.teiid.query.parser.QueryParser;
@@ -58,8 +57,6 @@
private transient Command command;
private transient TupleBuffer results;
- private AnalysisRecord analysisRecord;
-
private String[] types;
private CacheHint hint;
private int batchSize;
@@ -73,14 +70,6 @@
return this.uuid;
}
- public AnalysisRecord getAnalysisRecord() {
- return analysisRecord;
- }
-
- public void setAnalysisRecord(AnalysisRecord analysisRecord) {
- this.analysisRecord = analysisRecord;
- }
-
public TupleBuffer getResults() {
return results;
}
Modified: branches/7.4.x/engine/src/main/java/org/teiid/dqp/internal/process/RequestWorkItem.java
===================================================================
--- branches/7.4.x/engine/src/main/java/org/teiid/dqp/internal/process/RequestWorkItem.java 2011-08-04 15:04:00 UTC (rev 3360)
+++ branches/7.4.x/engine/src/main/java/org/teiid/dqp/internal/process/RequestWorkItem.java 2011-08-04 15:31:44 UTC (rev 3361)
@@ -456,7 +456,6 @@
CachedResults cr = rsCache.get(cacheId);
if (cr != null) {
this.resultsBuffer = cr.getResults();
- this.analysisRecord = cr.getAnalysisRecord();
request.initMetadata();
this.originalCommand = cr.getCommand(requestMsg.getCommandString(), request.metadata, pi);
request.validateAccess(this.originalCommand);
@@ -530,7 +529,6 @@
Determinism determinismLevel = processor.getContext().getDeterminismLevel();
CachedResults cr = new CachedResults();
cr.setCommand(originalCommand);
- cr.setAnalysisRecord(analysisRecord);
cr.setResults(resultsBuffer, processor.getProcessorPlan());
if (originalCommand.getCacheHint() != null) {
LogManager.logDetail(LogConstants.CTX_DQP, requestID, "Using cache hint", originalCommand.getCacheHint()); //$NON-NLS-1$
@@ -659,6 +657,7 @@
if (requestMsg.getShowPlan() == ShowPlan.DEBUG) {
response.setDebugLog(analysisRecord.getDebugLog());
}
+ this.analysisRecord = null;
}
}
Modified: branches/7.4.x/engine/src/main/java/org/teiid/query/analysis/AnalysisRecord.java
===================================================================
--- branches/7.4.x/engine/src/main/java/org/teiid/query/analysis/AnalysisRecord.java 2011-08-04 15:04:00 UTC (rev 3360)
+++ branches/7.4.x/engine/src/main/java/org/teiid/query/analysis/AnalysisRecord.java 2011-08-04 15:31:44 UTC (rev 3361)
@@ -53,7 +53,7 @@
* <li>Debug trace information, if requested</LI>
* </ul>
*/
-public class AnalysisRecord implements Serializable {
+public class AnalysisRecord {
// Common
public static final String PROP_OUTPUT_COLS = "Output Columns"; //$NON-NLS-1$
14 years, 8 months
teiid SVN: r3360 - in branches/7.4.x/documentation/admin-guide/src/main/docbook/en-US: images and 1 other directory.
by teiid-commits@lists.jboss.org
Author: tejones
Date: 2011-08-04 11:04:00 -0400 (Thu, 04 Aug 2011)
New Revision: 3360
Modified:
branches/7.4.x/documentation/admin-guide/src/main/docbook/en-US/content/admin-console.xml
branches/7.4.x/documentation/admin-guide/src/main/docbook/en-US/images/admin_console.png
Log:
TEIID-1693: Brought RHQ plugin documentation up-to-date
Modified: branches/7.4.x/documentation/admin-guide/src/main/docbook/en-US/content/admin-console.xml
===================================================================
--- branches/7.4.x/documentation/admin-guide/src/main/docbook/en-US/content/admin-console.xml 2011-08-04 14:50:37 UTC (rev 3359)
+++ branches/7.4.x/documentation/admin-guide/src/main/docbook/en-US/content/admin-console.xml 2011-08-04 15:04:00 UTC (rev 3360)
@@ -1,92 +1,199 @@
-<?xml version="1.0" encoding="UTF-8"?>
+<?xml version='1.0'?>
<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">
<chapter id="admin-console">
- <title>Teiid Admin Console</title>
- <para>The Teiid Admin Console is a web based administrative and monitoring tool for Teiid.
- Teiid's Admin Console is built using the <ulink url="http://www.jboss.org/embjopr">Embedded JOPR</ulink> library and adds a additional plugin into the Embeeded JOPR program already available in the
- <ulink url="http://www.jboss.org/jbossas">JBoss AS</ulink>.</para>
-
- <mediaobject>
- <imageobject>
- <imagedata scalefit="1" fileref="../images/admin_console.png"/>
- </imageobject>
- </mediaobject>
-
- <section>
- <title>What can be monitored and/or configured?</title>
- <para>Here are the steps to follow to install Teiid</para>
-
- <orderedlist>
- <listitem> <para><emphasis>The Teiid Runtime Engine</emphasis> (Data Services node in the tree)</para> </listitem>
- <listitem> <para><emphasis>VDBs</emphasis> - Virtual databases</para>
+ <title>Teiid Admin Console</title>
+ <para>The Teiid Admin Console is a web based administrative and
+ monitoring tool for Teiid. Teiid's Admin Console is built using
+ the <ulink url="http://www.jboss.org/embjopr">Embedded JOPR</ulink>
+ library and adds a additional plugin into the Embedded JOPR program
+ already available in the <ulink url="http://www.jboss.org/jbossas">
+ JBoss AS</ulink>.</para>
+ <mediaobject><imageobject>
+ <imagedata fileref="../images/admin_console.png" scalefit="1"/></imageobject></mediaobject>
+ <section>
+ <title>What can be monitored and/or configured?</title>
+ <para>Here are the steps to follow to install Teiid</para>
+ <orderedlist>
+ <listitem>
+ <para><emphasis>The Teiid Runtime Engine</emphasis> (Data
+ Services node in the tree)</para>
+ </listitem>
+ <listitem>
+ <para><emphasis>VDBs</emphasis> - Virtual databases</para>
+ <orderedlist>
+ <listitem>
+ <para><emphasis>Models</emphasis></para>
<orderedlist>
- <listitem> <para><emphasis>Models</emphasis></para>
- <orderedlist>
- <listitem> <para><emphasis>Source</emphasis>- these are physical sources</para></listitem>
- <listitem> <para><emphasis>Multi-source</emphasis> - these are multiple sourced models</para></listitem>
- <listitem> <para><emphasis>Logical</emphasis> - these are virtual sources</para></listitem>
- </orderedlist>
- </listitem>
- <listitem> <para><emphasis>Translator instances</emphasis>- any Translator instances defined for use by this VDB</para> </listitem>
+ <listitem>
+ <para><emphasis>Source</emphasis>- these are physical
+ sources</para>
+ </listitem>
+ <listitem>
+ <para><emphasis>Multi-source</emphasis> - these are
+ multiple sourced models</para>
+ </listitem>
+ <listitem>
+ <para><emphasis>Logical</emphasis> - these are virtual
+ sources</para>
+ </listitem>
</orderedlist>
+ </listitem>
+ <listitem>
+ <para><emphasis>Translator instances</emphasis>- any
+ Translator instances defined for use by this VDB</para>
+ </listitem>
+ <listitem>
+ <para><emphasis>Data Roles</emphasis>- any
+ data roles defined for use by this VDB</para>
+ </listitem>
+ </orderedlist>
+ </listitem>
+ <listitem>
+ <para>Translators - These are the extensions to supported
+ datasources that come with Teiid out-of-the-box.</para>
+ </listitem>
+ </orderedlist>
+ <note>
+ <para>The creation/modification of the datasource is managed by
+ the JBossAS plugin.</para>
+ </note>
+ <section>
+ <title>Configuration</title>
+ <orderedlist>
+ <listitem>
+ <para>Settings for the Data Services plugin</para>
</listitem>
- <listitem> <para>Translators - These are the extensions to supported datasources that come with Teiid out-of-the-box.</para> </listitem>
- </orderedlist>
-
- <note>
- <para>The creation/modification of the datasource is managed by the JBossAS plugin.</para>
- </note>
-
+ <listitem>
+ <para>Runtime Engine properties</para>
+ </listitem>
+ <listitem>
+ <para>Buffer Service</para>
+ </listitem>
+ <listitem>
+ <para>Jdbc Socket configuration</para>
+ </listitem>
+ <listitem>
+ <para>Session Service</para>
+ </listitem>
+ </orderedlist>
+ </section>
<section>
- <title>Configuration</title>
- <orderedlist>
- <listitem> <para>Runtime Engine properties</para> </listitem>
- <listitem> <para>Buffer Service</para> </listitem>
- <listitem> <para>Jdbc Socket configuration</para> </listitem>
- <listitem> <para>Session Service</para> </listitem>
- </orderedlist>
+ <title>Metrics</title>
+ <orderedlist>
+ <listitem>
+ <para>Long Running Query count</para>
+ </listitem>
+ <listitem>
+ <para>Active Query count</para>
+ </listitem>
+ <listitem>
+ <para>Active Session count</para>
+ </listitem>
+ <listitem>
+ <para>Prepared Plan Cache Hit Ratio %</para>
+ </listitem>
+ <listitem>
+ <para>Prepared Plan Cache Size</para>
+ </listitem>
+ <listitem>
+ <para>Prepared Plan Cache # of Requests</para>
+ </listitem>
+ <listitem>
+ <para>ResultSet Cache Hit Ratio %</para>
+ </listitem>
+ <listitem>
+ <para>ResultSet Cache Size</para>
+ </listitem>
+ <listitem>
+ <para>ResultSet Cache # of Requests</para>
+ </listitem>
+ <listitem>
+ <para>Used Buffer Space</para>
+ </listitem>
+ </orderedlist>
</section>
-
<section>
- <title>Metrics</title>
+ <title>Control (Operations)</title>
+ <listitem>
+ <para>Data Services Engine</para>
<orderedlist>
- <listitem> <para>Long Running Query count</para> </listitem>
- <listitem> <para>Active Query count</para> </listitem>
- <listitem> <para>Active Session count</para> </listitem>
+ <listitem>
+ <para>View Long Running Queries</para>
+ </listitem>
+ <listitem>
+ <para>View Current Sessions</para>
+ </listitem>
+ <listitem>
+ <para>Deploy a VDB via URL</para>
+ </listitem>
+ <listitem>
+ <para>Terminate Session</para>
+ </listitem>
+ <listitem>
+ <para>View Current Requests</para>
+ </listitem>
+ <listitem>
+ <para>Terminate requests</para>
+ </listitem>
+ <listitem>
+ <para>View Current Transactions</para>
+ </listitem>
+ <listitem>
+ <para>Terminate Transaction</para>
+ </listitem>
</orderedlist>
- </section>
-
- <section>
- <title>Control (Operations)</title>
+ </listitem>
+ <listitem>
+ <para>Virtual Database</para>
<orderedlist>
- <listitem> <para>View Long Running Queries</para> </listitem>
- <listitem> <para>View Current Sessions</para> </listitem>
- <listitem> <para>Terminate Session</para> </listitem>
- <listitem> <para>View Current Requests</para> </listitem>
- <listitem> <para>Terminate requests</para> </listitem>
- <listitem> <para>View Current Transactions</para> </listitem>
- <listitem> <para>Terminate Transaction</para> </listitem>
+ <listitem>
+ <para>View VDB Requests</para>
+ </listitem>
+ <listitem>
+ <para>View VDB Sessions</para>
+ </listitem>
+ <listitem>
+ <para>List Materialized View Info</para>
+ </listitem>
+ <listitem>
+ <para>Refresh a Materialized View</para>
+ </listitem>
+ <listitem>
+ <para>Clear Cache</para>
+ </listitem>
</orderedlist>
+ </listitem>
</section>
-
<section id="vdb_deploy">
- <title>Deploying the VDB</title>
- <para>VDB archive files created it the Designer Tool or Dynamic VDBs can be deployed into Teiid server using
- the Admin Console.</para>
-
- <orderedlist>
- <listitem> <para>Select the Virtual Database node in the Admin Console tree and click the Add New Resource button.</para> </listitem>
- <listitem> <para>Select the VDB archive file from the file system and click continue.</para> </listitem>
- <listitem> <para>The VDB will deploy if no fatal errors are found in the archive. The status of
- the VDB will be UP if no errors are found with the models in the VDB.</para> </listitem>
- <listitem> <para>If there are model errors, the VDB will be deployed with a status of DOWN and the errors will be
- listed on the configuration tab of the VDB. VDBs that are not UP will be marked with a red X in the tree.</para> </listitem>
- </orderedlist>
-
- <para>Only Model's "connection-jndi-name" can be modified using this tool by clicking on the "configuration"
- tab, all other proeprties are read-only.</para>
- </section>
-
- </section>
-
-</chapter>
\ No newline at end of file
+ <title>Deploying the VDB</title>
+ <para>VDB archive files created it the Designer Tool or Dynamic
+ VDBs can be deployed into Teiid server using the Admin
+ Console.</para>
+ <orderedlist>
+ <listitem>
+ <para>Select the Virtual Database node in the Admin Console
+ tree and click the Add New Resource button.</para>
+ </listitem>
+ <listitem>
+ <para>Select the VDB archive file from the file system and
+ click continue.</para>
+ </listitem>
+ <listitem>
+ <para>The VDB will deploy if no fatal errors are found in the
+ archive. The status of the VDB will be UP if no errors are
+ found with the models in the VDB.</para>
+ </listitem>
+ <listitem>
+ <para>If there are model errors, the VDB will be deployed
+ with a status of DOWN and the errors will be listed on the
+ configuration tab of the VDB. VDBs that are not UP will be
+ marked with a red X in the tree.</para>
+ </listitem>
+ </orderedlist>
+ <para>Only Model's "connection-jndi-name" can be
+ modified using this tool by clicking on the
+ "configuration" tab, all other properties are
+ read-only.</para>
+ </section>
+ </section>
+</chapter>
Modified: branches/7.4.x/documentation/admin-guide/src/main/docbook/en-US/images/admin_console.png
===================================================================
(Binary files differ)
14 years, 8 months
teiid SVN: r3359 - in trunk: api/src/main/java/org/teiid/language/visitor and 27 other directories.
by teiid-commits@lists.jboss.org
Author: shawkins
Date: 2011-08-04 10:50:37 -0400 (Thu, 04 Aug 2011)
New Revision: 3359
Modified:
trunk/api/src/main/java/org/teiid/language/SQLConstants.java
trunk/api/src/main/java/org/teiid/language/visitor/SQLStringVisitor.java
trunk/api/src/main/java/org/teiid/translator/SourceSystemFunctions.java
trunk/build/kits/jboss-container/teiid-releasenotes.html
trunk/connectors/translator-jdbc/src/main/java/org/teiid/translator/jdbc/db2/DB2ExecutionFactory.java
trunk/connectors/translator-jdbc/src/main/java/org/teiid/translator/jdbc/derby/DerbyExecutionFactory.java
trunk/connectors/translator-jdbc/src/main/java/org/teiid/translator/jdbc/h2/H2ExecutionFactory.java
trunk/connectors/translator-jdbc/src/main/java/org/teiid/translator/jdbc/hsql/HsqlExecutionFactory.java
trunk/connectors/translator-jdbc/src/main/java/org/teiid/translator/jdbc/mysql/MySQLExecutionFactory.java
trunk/connectors/translator-jdbc/src/main/java/org/teiid/translator/jdbc/oracle/OracleExecutionFactory.java
trunk/connectors/translator-jdbc/src/main/java/org/teiid/translator/jdbc/postgresql/PostgreSQLExecutionFactory.java
trunk/connectors/translator-jdbc/src/main/java/org/teiid/translator/jdbc/teiid/TeiidExecutionFactory.java
trunk/connectors/translator-jdbc/src/main/java/org/teiid/translator/jdbc/teradata/TeradataExecutionFactory.java
trunk/connectors/translator-jdbc/src/test/java/org/teiid/translator/jdbc/db2/TestDB2SqlTranslator.java
trunk/connectors/translator-jdbc/src/test/java/org/teiid/translator/jdbc/derby/TestDerbyCapabilities.java
trunk/documentation/reference/src/main/docbook/en-US/content/scalar_functions.xml
trunk/engine/src/main/java/org/teiid/query/function/FunctionMethods.java
trunk/engine/src/main/java/org/teiid/query/function/source/SystemSource.java
trunk/engine/src/main/java/org/teiid/query/resolver/util/ResolverVisitor.java
trunk/engine/src/main/java/org/teiid/query/rewriter/QueryRewriter.java
trunk/engine/src/main/java/org/teiid/query/sql/visitor/SQLStringVisitor.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/function/TestFunctionLibrary.java
trunk/engine/src/test/java/org/teiid/query/parser/TestParser.java
trunk/engine/src/test/java/org/teiid/query/processor/eval/TestExpressionEvaluator.java
trunk/engine/src/test/java/org/teiid/query/resolver/TestResolver.java
trunk/engine/src/test/java/org/teiid/query/rewriter/TestQueryRewriter.java
trunk/test-integration/common/src/test/java/org/teiid/connector/visitor/util/TestSQLStringVisitor.java
Log:
TEIID-1694 adding support for trim and standard substring syntax
Modified: trunk/api/src/main/java/org/teiid/language/SQLConstants.java
===================================================================
--- trunk/api/src/main/java/org/teiid/language/SQLConstants.java 2011-08-04 12:09:55 UTC (rev 3358)
+++ trunk/api/src/main/java/org/teiid/language/SQLConstants.java 2011-08-04 14:50:37 UTC (rev 3359)
@@ -111,6 +111,8 @@
public static final String INSTEAD = "INSTEAD"; //$NON-NLS-1$
public static final String ENABLED = "ENABLED"; //$NON-NLS-1$
public static final String DISABLED = "DISABLED"; //$NON-NLS-1$
+
+ public static final String TRIM = "TRIM";
}
public interface Reserved {
Modified: trunk/api/src/main/java/org/teiid/language/visitor/SQLStringVisitor.java
===================================================================
--- trunk/api/src/main/java/org/teiid/language/visitor/SQLStringVisitor.java 2011-08-04 12:09:55 UTC (rev 3358)
+++ trunk/api/src/main/java/org/teiid/language/visitor/SQLStringVisitor.java 2011-08-04 14:50:37 UTC (rev 3359)
@@ -410,7 +410,20 @@
}
}
buffer.append(Tokens.RPAREN);
-
+ } else if (name.equalsIgnoreCase(NonReserved.TRIM)) {
+ buffer.append(name);
+ buffer.append(Tokens.LPAREN);
+ String value = (String)((Literal)args.get(0)).getValue();
+ if (!value.equalsIgnoreCase(BOTH)) {
+ buffer.append(value);
+ buffer.append(Tokens.SPACE);
+ }
+ append(args.get(1));
+ buffer.append(" "); //$NON-NLS-1$
+ buffer.append(FROM);
+ buffer.append(" "); //$NON-NLS-1$
+ buffer.append(args.get(2));
+ buffer.append(")"); //$NON-NLS-1$
} else {
buffer.append(obj.getName())
Modified: trunk/api/src/main/java/org/teiid/translator/SourceSystemFunctions.java
===================================================================
--- trunk/api/src/main/java/org/teiid/translator/SourceSystemFunctions.java 2011-08-04 12:09:55 UTC (rev 3358)
+++ trunk/api/src/main/java/org/teiid/translator/SourceSystemFunctions.java 2011-08-04 14:50:37 UTC (rev 3359)
@@ -58,6 +58,10 @@
public static final String SUBSTRING = "substring"; //$NON-NLS-1$
public static final String TO_BYTES = "to_bytes"; //$NON-NLS-1$
public static final String TO_CHARS = "to_chars"; //$NON-NLS-1$
+ /**
+ * The trim function is only used for a non-space trim character
+ */
+ public static final String TRIM = "trim"; //$NON-NLS-1$
public static final String UCASE = "ucase"; //$NON-NLS-1$
public static final String UNESCAPE = "unescape"; //$NON-NLS-1$
Modified: trunk/build/kits/jboss-container/teiid-releasenotes.html
===================================================================
--- trunk/build/kits/jboss-container/teiid-releasenotes.html 2011-08-04 12:09:55 UTC (rev 3358)
+++ trunk/build/kits/jboss-container/teiid-releasenotes.html 2011-08-04 14:50:37 UTC (rev 3359)
@@ -35,7 +35,7 @@
<LI><B>Streaming XQuery</B> - in situations where document projection applies if the XMLQUERY/XMLTABLE path expressions meet certain conditions, then the incoming document will not only be projected, but the independent subtrees will be processed without loading the entire document. This allows for nearly arbitrarily large XML documents to be processed. See the Reference for more.
<LI><B>Logging Procedures</B> - added SYSADMIN.isLoggable and SYSADMIN.logMsg to aid in debugging procedure logic.
<LI><B>ANSI OFFSET/FETCH FIRST</B> - instead of the limit clause, a standard OFFSET and/or FETCH FIRST/NEXT clause can be used to limit results.
- <LI><B>ODBC Cursors</B> - Capability to use "UseDeclareFetch" with ODBC is added. This enables user to read the results in batches, especially useful when dealing with large row count of results.
+ <LI><B>ODBC Cursors</B> - added the capability to use "UseDeclareFetch" with ODBC. This enables users to read results in batches, which is especially useful when dealing with large row counts.
<LI><B>Internal Materialized Views</B>
<UL>
<LI><B>Distributed Refresh</B> - When a internal materialized view is refreshed at one node, an event is issued to all other nodes in the cluster to asynchronously fetch the new contents.
Modified: trunk/connectors/translator-jdbc/src/main/java/org/teiid/translator/jdbc/db2/DB2ExecutionFactory.java
===================================================================
--- trunk/connectors/translator-jdbc/src/main/java/org/teiid/translator/jdbc/db2/DB2ExecutionFactory.java 2011-08-04 12:09:55 UTC (rev 3358)
+++ trunk/connectors/translator-jdbc/src/main/java/org/teiid/translator/jdbc/db2/DB2ExecutionFactory.java 2011-08-04 14:50:37 UTC (rev 3359)
@@ -23,9 +23,16 @@
package org.teiid.translator.jdbc.db2;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.List;
+import org.teiid.language.Expression;
+import org.teiid.language.Function;
+import org.teiid.language.Literal;
+import org.teiid.translator.SourceSystemFunctions;
import org.teiid.translator.Translator;
+import org.teiid.translator.TranslatorException;
+import org.teiid.translator.jdbc.FunctionModifier;
@Translator(name="db2", description="A translator for IBM DB2 Database")
public class DB2ExecutionFactory extends BaseDB2ExecutionFactory {
@@ -80,6 +87,7 @@
supportedFunctions.add("RIGHT"); //$NON-NLS-1$
supportedFunctions.add("RTRIM"); //$NON-NLS-1$
supportedFunctions.add("SUBSTRING"); //$NON-NLS-1$
+ supportedFunctions.add(SourceSystemFunctions.TRIM);
//supportedFunctions.add("TRANSLATE"); //$NON-NLS-1$
supportedFunctions.add("UCASE"); //$NON-NLS-1$
supportedFunctions.add("UPPER"); //$NON-NLS-1$
@@ -129,5 +137,18 @@
public boolean supportsElementaryOlapOperations() {
return getDatabaseVersion().compareTo(NINE_1) >= 0;
}
-
+
+ @Override
+ public void start() throws TranslatorException {
+ super.start();
+ registerFunctionModifier(SourceSystemFunctions.TRIM, new FunctionModifier() {
+
+ @Override
+ public List<?> translate(Function function) {
+ List<Expression> p = function.getParameters();
+ return Arrays.asList("STRIP(", p.get(2), ", ", ((Literal)p.get(0)).getValue(), ", ", p.get(1), ")"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
+ }
+ });
+ }
+
}
Modified: trunk/connectors/translator-jdbc/src/main/java/org/teiid/translator/jdbc/derby/DerbyExecutionFactory.java
===================================================================
--- trunk/connectors/translator-jdbc/src/main/java/org/teiid/translator/jdbc/derby/DerbyExecutionFactory.java 2011-08-04 12:09:55 UTC (rev 3358)
+++ trunk/connectors/translator-jdbc/src/main/java/org/teiid/translator/jdbc/derby/DerbyExecutionFactory.java 2011-08-04 14:50:37 UTC (rev 3359)
@@ -40,6 +40,7 @@
public static final String TEN_1 = "10.1"; //$NON-NLS-1$
public static final String TEN_2 = "10.2"; //$NON-NLS-1$
+ public static final String TEN_3 = "10.3"; //$NON-NLS-1$
public static final String TEN_4 = "10.4"; //$NON-NLS-1$
public static final String TEN_5 = "10.5"; //$NON-NLS-1$
@@ -130,6 +131,9 @@
//supportedFunctions.add("RPAD"); //$NON-NLS-1$
supportedFunctions.add("RTRIM"); //$NON-NLS-1$
supportedFunctions.add("SUBSTRING"); //$NON-NLS-1$
+ if (getDatabaseVersion().compareTo(TEN_3) >= 0) {
+ supportedFunctions.add(SourceSystemFunctions.TRIM);
+ }
supportedFunctions.add("UCASE"); //$NON-NLS-1$
// These are executed within the server and never pushed down
Modified: trunk/connectors/translator-jdbc/src/main/java/org/teiid/translator/jdbc/h2/H2ExecutionFactory.java
===================================================================
--- trunk/connectors/translator-jdbc/src/main/java/org/teiid/translator/jdbc/h2/H2ExecutionFactory.java 2011-08-04 12:09:55 UTC (rev 3358)
+++ trunk/connectors/translator-jdbc/src/main/java/org/teiid/translator/jdbc/h2/H2ExecutionFactory.java 2011-08-04 14:50:37 UTC (rev 3359)
@@ -28,9 +28,9 @@
import java.util.ArrayList;
import java.util.List;
+import org.teiid.translator.SourceSystemFunctions;
import org.teiid.translator.Translator;
import org.teiid.translator.TranslatorException;
-import org.teiid.translator.SourceSystemFunctions;
import org.teiid.translator.jdbc.AliasModifier;
import org.teiid.translator.jdbc.ConvertModifier;
import org.teiid.translator.jdbc.FunctionModifier;
@@ -139,6 +139,7 @@
supportedFunctions.add(SourceSystemFunctions.RPAD);
supportedFunctions.add(SourceSystemFunctions.RTRIM);
supportedFunctions.add(SourceSystemFunctions.SUBSTRING);
+ supportedFunctions.add(SourceSystemFunctions.TRIM);
supportedFunctions.add(SourceSystemFunctions.UCASE);
supportedFunctions.add(SourceSystemFunctions.UNESCAPE);
Modified: trunk/connectors/translator-jdbc/src/main/java/org/teiid/translator/jdbc/hsql/HsqlExecutionFactory.java
===================================================================
--- trunk/connectors/translator-jdbc/src/main/java/org/teiid/translator/jdbc/hsql/HsqlExecutionFactory.java 2011-08-04 12:09:55 UTC (rev 3358)
+++ trunk/connectors/translator-jdbc/src/main/java/org/teiid/translator/jdbc/hsql/HsqlExecutionFactory.java 2011-08-04 14:50:37 UTC (rev 3359)
@@ -28,9 +28,9 @@
import java.util.ArrayList;
import java.util.List;
+import org.teiid.translator.SourceSystemFunctions;
import org.teiid.translator.Translator;
import org.teiid.translator.TranslatorException;
-import org.teiid.translator.SourceSystemFunctions;
import org.teiid.translator.jdbc.ConvertModifier;
import org.teiid.translator.jdbc.FunctionModifier;
import org.teiid.translator.jdbc.JDBCExecutionFactory;
@@ -125,6 +125,7 @@
supportedFunctions.add(SourceSystemFunctions.RPAD);
supportedFunctions.add(SourceSystemFunctions.RTRIM);
supportedFunctions.add(SourceSystemFunctions.SUBSTRING);
+ supportedFunctions.add(SourceSystemFunctions.TRIM);
supportedFunctions.add(SourceSystemFunctions.UCASE);
supportedFunctions.add(SourceSystemFunctions.DAYNAME);
Modified: trunk/connectors/translator-jdbc/src/main/java/org/teiid/translator/jdbc/mysql/MySQLExecutionFactory.java
===================================================================
--- trunk/connectors/translator-jdbc/src/main/java/org/teiid/translator/jdbc/mysql/MySQLExecutionFactory.java 2011-08-04 12:09:55 UTC (rev 3358)
+++ trunk/connectors/translator-jdbc/src/main/java/org/teiid/translator/jdbc/mysql/MySQLExecutionFactory.java 2011-08-04 14:50:37 UTC (rev 3359)
@@ -177,6 +177,7 @@
supportedFunctions.add(SourceSystemFunctions.RPAD);
supportedFunctions.add(SourceSystemFunctions.RTRIM);
supportedFunctions.add(SourceSystemFunctions.SUBSTRING);
+ supportedFunctions.add(SourceSystemFunctions.TRIM);
supportedFunctions.add(SourceSystemFunctions.UCASE);
// These are executed within the server and never pushed down
Modified: trunk/connectors/translator-jdbc/src/main/java/org/teiid/translator/jdbc/oracle/OracleExecutionFactory.java
===================================================================
--- trunk/connectors/translator-jdbc/src/main/java/org/teiid/translator/jdbc/oracle/OracleExecutionFactory.java 2011-08-04 12:09:55 UTC (rev 3358)
+++ trunk/connectors/translator-jdbc/src/main/java/org/teiid/translator/jdbc/oracle/OracleExecutionFactory.java 2011-08-04 14:50:37 UTC (rev 3359)
@@ -454,6 +454,7 @@
supportedFunctions.add("RTRIM"); //$NON-NLS-1$
supportedFunctions.add("SUBSTRING"); //$NON-NLS-1$
supportedFunctions.add("TRANSLATE"); //$NON-NLS-1$
+ supportedFunctions.add(SourceSystemFunctions.TRIM);
supportedFunctions.add("UCASE"); //$NON-NLS-1$
supportedFunctions.add("UPPER"); //$NON-NLS-1$
supportedFunctions.add("HOUR"); //$NON-NLS-1$
Modified: trunk/connectors/translator-jdbc/src/main/java/org/teiid/translator/jdbc/postgresql/PostgreSQLExecutionFactory.java
===================================================================
--- trunk/connectors/translator-jdbc/src/main/java/org/teiid/translator/jdbc/postgresql/PostgreSQLExecutionFactory.java 2011-08-04 12:09:55 UTC (rev 3358)
+++ trunk/connectors/translator-jdbc/src/main/java/org/teiid/translator/jdbc/postgresql/PostgreSQLExecutionFactory.java 2011-08-04 14:50:37 UTC (rev 3359)
@@ -302,6 +302,7 @@
supportedFunctions.add("RPAD"); //$NON-NLS-1$
supportedFunctions.add("RTRIM"); //$NON-NLS-1$
supportedFunctions.add("SUBSTRING"); //$NON-NLS-1$
+ supportedFunctions.add(SourceSystemFunctions.TRIM);
supportedFunctions.add("UCASE"); //$NON-NLS-1$
supportedFunctions.add("UPPER"); //$NON-NLS-1$
Modified: trunk/connectors/translator-jdbc/src/main/java/org/teiid/translator/jdbc/teiid/TeiidExecutionFactory.java
===================================================================
--- trunk/connectors/translator-jdbc/src/main/java/org/teiid/translator/jdbc/teiid/TeiidExecutionFactory.java 2011-08-04 12:09:55 UTC (rev 3358)
+++ trunk/connectors/translator-jdbc/src/main/java/org/teiid/translator/jdbc/teiid/TeiidExecutionFactory.java 2011-08-04 14:50:37 UTC (rev 3359)
@@ -145,14 +145,18 @@
if (getDatabaseVersion().compareTo(SEVEN_3) >= 0) {
supportedFunctions.add(SourceSystemFunctions.UNESCAPE);
-
- if (getDatabaseVersion().compareTo(SEVEN_4) >= 0) {
- supportedFunctions.add(SourceSystemFunctions.UUID);
- supportedFunctions.add(SourceSystemFunctions.ARRAY_GET);
- supportedFunctions.add(SourceSystemFunctions.ARRAY_LENGTH);
- }
}
+ if (getDatabaseVersion().compareTo(SEVEN_4) >= 0) {
+ supportedFunctions.add(SourceSystemFunctions.UUID);
+ supportedFunctions.add(SourceSystemFunctions.ARRAY_GET);
+ supportedFunctions.add(SourceSystemFunctions.ARRAY_LENGTH);
+ }
+
+ if (getDatabaseVersion().compareTo(SEVEN_5) >= 0) {
+ supportedFunctions.add(SourceSystemFunctions.TRIM);
+ }
+
return supportedFunctions;
}
Modified: trunk/connectors/translator-jdbc/src/main/java/org/teiid/translator/jdbc/teradata/TeradataExecutionFactory.java
===================================================================
--- trunk/connectors/translator-jdbc/src/main/java/org/teiid/translator/jdbc/teradata/TeradataExecutionFactory.java 2011-08-04 12:09:55 UTC (rev 3358)
+++ trunk/connectors/translator-jdbc/src/main/java/org/teiid/translator/jdbc/teradata/TeradataExecutionFactory.java 2011-08-04 14:50:37 UTC (rev 3359)
@@ -251,6 +251,7 @@
supportedFunctions.add(SourceSystemFunctions.SQRT);
supportedFunctions.add(SourceSystemFunctions.SUBSTRING);
supportedFunctions.add(SourceSystemFunctions.TAN);
+ supportedFunctions.add(SourceSystemFunctions.TRIM);
supportedFunctions.add(SourceSystemFunctions.UCASE);
supportedFunctions.add(SourceSystemFunctions.YEAR);
Modified: trunk/connectors/translator-jdbc/src/test/java/org/teiid/translator/jdbc/db2/TestDB2SqlTranslator.java
===================================================================
--- trunk/connectors/translator-jdbc/src/test/java/org/teiid/translator/jdbc/db2/TestDB2SqlTranslator.java 2011-08-04 12:09:55 UTC (rev 3358)
+++ trunk/connectors/translator-jdbc/src/test/java/org/teiid/translator/jdbc/db2/TestDB2SqlTranslator.java 2011-08-04 14:50:37 UTC (rev 3359)
@@ -270,5 +270,14 @@
input, output,
TRANSLATOR);
}
+
+ @Test public void testTrim() throws Exception {
+ String input = "SELECT trim(leading 'x' from stringnum) FROM BQT1.SMALLA"; //$NON-NLS-1$
+ String output = "SELECT STRIP(SmallA.StringNum, leading, 'x') FROM SmallA"; //$NON-NLS-1$
+ TranslationHelper.helpTestVisitor(TranslationHelper.BQT_VDB,
+ input, output,
+ TRANSLATOR);
+ }
+
}
Modified: trunk/connectors/translator-jdbc/src/test/java/org/teiid/translator/jdbc/derby/TestDerbyCapabilities.java
===================================================================
--- trunk/connectors/translator-jdbc/src/test/java/org/teiid/translator/jdbc/derby/TestDerbyCapabilities.java 2011-08-04 12:09:55 UTC (rev 3358)
+++ trunk/connectors/translator-jdbc/src/test/java/org/teiid/translator/jdbc/derby/TestDerbyCapabilities.java 2011-08-04 14:50:37 UTC (rev 3359)
@@ -22,9 +22,7 @@
package org.teiid.translator.jdbc.derby;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.*;
import org.junit.Test;
@@ -41,7 +39,7 @@
DerbyExecutionFactory derbyCapabilities = new DerbyExecutionFactory();
assertEquals(27, derbyCapabilities.getSupportedFunctions().size());
derbyCapabilities.setDatabaseVersion(DerbyExecutionFactory.TEN_4);
- assertEquals(43, derbyCapabilities.getSupportedFunctions().size());
+ assertEquals(44, derbyCapabilities.getSupportedFunctions().size());
}
}
Modified: trunk/documentation/reference/src/main/docbook/en-US/content/scalar_functions.xml
===================================================================
--- trunk/documentation/reference/src/main/docbook/en-US/content/scalar_functions.xml 2011-08-04 12:09:55 UTC (rev 3358)
+++ trunk/documentation/reference/src/main/docbook/en-US/content/scalar_functions.xml 2011-08-04 14:50:37 UTC (rev 3359)
@@ -1005,6 +1005,7 @@
<row>
<entry>
<para>SUBSTRING(x, y)</para>
+ <para>SUBSTRING(x FROM y)</para>
</entry>
<entry>
<para>Get substring from x, from position y to the end of x
@@ -1017,6 +1018,7 @@
<row>
<entry>
<para>SUBSTRING(x, y, z)</para>
+ <para>SUBSTRING(x FROM y FOR z)</para>
</entry>
<entry>
<para>Get substring from x from position y with length z
@@ -1063,6 +1065,18 @@
</row>
<row>
<entry>
+ <para>TRIM([[LEADING|TRAILING|BOTH] [x] FROM] y)</para>
+ </entry>
+ <entry>
+ <para>Trim the leading, trailing, or both ends of a string y of character x.
+ If LEADING/TRAILING/BOTH is not specified, BOTH is used. If no trim character x is specficed then the blank space ' ' is used.</para>
+ </entry>
+ <entry>
+ <para>x in {character}, y in {string}</para>
+ </entry>
+ </row>
+ <row>
+ <entry>
<para>UCASE(x)</para>
</entry>
<entry>
Modified: trunk/engine/src/main/java/org/teiid/query/function/FunctionMethods.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/function/FunctionMethods.java 2011-08-04 12:09:55 UTC (rev 3358)
+++ trunk/engine/src/main/java/org/teiid/query/function/FunctionMethods.java 2011-08-04 14:50:37 UTC (rev 3359)
@@ -56,6 +56,7 @@
import org.teiid.core.types.InputStreamFactory.BlobInputStreamFactory;
import org.teiid.core.types.InputStreamFactory.ClobInputStreamFactory;
import org.teiid.core.util.TimestampWithTimezone;
+import org.teiid.language.SQLConstants;
import org.teiid.language.SQLConstants.NonReserved;
import org.teiid.query.QueryPlugin;
import org.teiid.query.util.CommandContext;
@@ -694,14 +695,30 @@
return new Integer(str.indexOf(sub, start.intValue() - 1) + 1);
}
+ public static String trim(String trimSpec, String trimChar, String string) throws FunctionExecutionException {
+ if (trimChar.length() != 1) {
+ throw new FunctionExecutionException(QueryPlugin.Util.getString("SQLParser.Invalid_char", "trim char", trimChar)); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+ if (!trimSpec.equalsIgnoreCase(SQLConstants.Reserved.LEADING)) {
+ string = rightTrim(string, trimChar.charAt(0));
+ }
+ if (!trimSpec.equalsIgnoreCase(SQLConstants.Reserved.TRAILING)) {
+ string = leftTrim(string, trimChar.charAt(0));
+ }
+ return string;
+ }
+
// ================== Function = lefttrim =====================
private static final char SPACE = ' ';
- public static Object leftTrim(String string) {
+ public static String leftTrim(String string, char trimChar) {
for(int i=0; i<string.length(); i++) {
- if(string.charAt(i) != SPACE) {
+ if(string.charAt(i) != trimChar) {
// end of trim, return what's left
+ if (i==0) {
+ return string;
+ }
return new String(string.substring(i));
}
}
@@ -709,13 +726,21 @@
// All spaces, so trim it all
return ""; //$NON-NLS-1$
}
+
+
+ public static String leftTrim(String string) {
+ return leftTrim(string, SPACE);
+ }
// ================== Function = righttrim =====================
- public static Object rightTrim(String string) {
+ public static String rightTrim(String string, char trimChar) {
for(int i=string.length()-1; i>=0; i--) {
- if(string.charAt(i) != SPACE) {
+ if(string.charAt(i) != trimChar) {
// end of trim, return what's left
+ if (i==string.length()-1) {
+ return string;
+ }
return new String(string.substring(0, i+1));
}
}
@@ -723,6 +748,10 @@
// All spaces, so trim it all
return ""; //$NON-NLS-1$
}
+
+ public static Object rightTrim(String string) {
+ return rightTrim(string, SPACE);
+ }
// ================== Function = replace =====================
Modified: trunk/engine/src/main/java/org/teiid/query/function/source/SystemSource.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/function/source/SystemSource.java 2011-08-04 12:09:55 UTC (rev 3358)
+++ trunk/engine/src/main/java/org/teiid/query/function/source/SystemSource.java 2011-08-04 14:50:37 UTC (rev 3359)
@@ -29,8 +29,8 @@
import org.teiid.core.types.DataTypeManager;
import org.teiid.metadata.FunctionParameter;
+import org.teiid.metadata.FunctionMethod.Determinism;
import org.teiid.metadata.FunctionMethod.PushDown;
-import org.teiid.metadata.FunctionMethod.Determinism;
import org.teiid.query.QueryPlugin;
import org.teiid.query.function.FunctionLibrary;
import org.teiid.query.function.FunctionMetadataSource;
@@ -196,7 +196,18 @@
addUuidFunction();
addArrayGet();
addArrayLength();
+ addTrimFunction();
}
+
+ private void addTrimFunction() {
+ functions.add(
+ new FunctionMethod(SourceSystemFunctions.TRIM, QueryPlugin.Util.getString("SystemSource.trim_desc"), STRING, FUNCTION_CLASS, SourceSystemFunctions.TRIM,//$NON-NLS-1$
+ new FunctionParameter[] {
+ new FunctionParameter("spec", DataTypeManager.DefaultDataTypes.STRING, QueryPlugin.Util.getString("SystemSource.trim_arg1")),//$NON-NLS-1$ //$NON-NLS-2$
+ new FunctionParameter("trimChar", DataTypeManager.DefaultDataTypes.STRING, QueryPlugin.Util.getString("SystemSource.trim_arg2")),//$NON-NLS-1$ //$NON-NLS-2$
+ new FunctionParameter("string", DataTypeManager.DefaultDataTypes.STRING, QueryPlugin.Util.getString("SystemSource.trim_arg3")) }, //$NON-NLS-1$ //$NON-NLS-2$
+ new FunctionParameter("result", DataTypeManager.DefaultDataTypes.STRING, QueryPlugin.Util.getString("SystemSource.trim_result")) ) ); //$NON-NLS-1$ //$NON-NLS-2$
+ }
private void addArrayLength() {
functions.add(new FunctionMethod(SourceSystemFunctions.ARRAY_LENGTH, QueryPlugin.Util.getString("SystemSource.array_length_desc"), MISCELLANEOUS, PushDown.CAN_PUSHDOWN, FUNCTION_CLASS, SourceSystemFunctions.ARRAY_LENGTH, //$NON-NLS-1$
Modified: trunk/engine/src/main/java/org/teiid/query/resolver/util/ResolverVisitor.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/resolver/util/ResolverVisitor.java 2011-08-04 12:09:55 UTC (rev 3358)
+++ trunk/engine/src/main/java/org/teiid/query/resolver/util/ResolverVisitor.java 2011-08-04 14:50:37 UTC (rev 3359)
@@ -529,11 +529,11 @@
if(fd.getName().equalsIgnoreCase(FunctionLibrary.CONVERT) || fd.getName().equalsIgnoreCase(FunctionLibrary.CAST)) {
String dataType = (String) ((Constant)args[1]).getValue();
- Class dataTypeClass = DataTypeManager.getDataTypeClass(dataType);
+ Class<?> dataTypeClass = DataTypeManager.getDataTypeClass(dataType);
fd = library.findTypedConversionFunction(args[0].getType(), dataTypeClass);
// Verify that the type conversion from src to type is even valid
- Class srcTypeClass = args[0].getType();
+ Class<?> srcTypeClass = args[0].getType();
if(srcTypeClass != null && dataTypeClass != null &&
!srcTypeClass.equals(dataTypeClass) &&
!DataTypeManager.isTransformable(srcTypeClass, dataTypeClass)) {
@@ -545,7 +545,6 @@
fd = library.copyFunctionChangeReturnType(fd, lookup.getReturnElement().getType());
}
- // Resolve the function
function.setFunctionDescriptor(fd);
function.setType(fd.getReturnType());
}
Modified: trunk/engine/src/main/java/org/teiid/query/rewriter/QueryRewriter.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/rewriter/QueryRewriter.java 2011-08-04 12:09:55 UTC (rev 3358)
+++ trunk/engine/src/main/java/org/teiid/query/rewriter/QueryRewriter.java 2011-08-04 14:50:37 UTC (rev 3359)
@@ -55,6 +55,7 @@
import org.teiid.core.types.Transform;
import org.teiid.core.util.Assertion;
import org.teiid.core.util.TimestampWithTimezone;
+import org.teiid.language.SQLConstants;
import org.teiid.language.SQLConstants.NonReserved;
import org.teiid.query.QueryPlugin;
import org.teiid.query.eval.Evaluator;
@@ -2281,6 +2282,7 @@
FUNCTION_MAP.put(FunctionLibrary.PARSETIME.toLowerCase(), 7);
FUNCTION_MAP.put(FunctionLibrary.FORMATDATE.toLowerCase(), 8);
FUNCTION_MAP.put(FunctionLibrary.FORMATTIME.toLowerCase(), 9);
+ FUNCTION_MAP.put(SourceSystemFunctions.TRIM.toLowerCase(), 10);
}
private Expression rewriteFunction(Function function) throws TeiidComponentException, TeiidProcessingException{
@@ -2407,7 +2409,27 @@
function.getArgs()[0] = ResolverUtil.getConversion(function.getArg(0), DataTypeManager.getDataTypeName(function.getArg(0).getType()), DataTypeManager.DefaultDataTypes.TIMESTAMP, false, funcLibrary);
break;
}
+ case 10: {
+ if (new Constant(" ").equals(function.getArg(1))) { //$NON-NLS-1$
+ String spec = (String)((Constant)function.getArg(0)).getValue();
+ Expression string = function.getArg(2);
+ if (!SQLConstants.Reserved.TRAILING.equalsIgnoreCase(spec)) {
+ function = new Function(SourceSystemFunctions.LTRIM, new Expression[] {string});
+ FunctionDescriptor descriptor = funcLibrary.findFunction(SourceSystemFunctions.LTRIM, new Class[] { DataTypeManager.DefaultDataClasses.STRING });
+ function.setFunctionDescriptor(descriptor);
+ function.setType(DataTypeManager.DefaultDataClasses.STRING);
+ string = function;
+ }
+ if (!SQLConstants.Reserved.LEADING.equalsIgnoreCase(spec)) {
+ function = new Function(SourceSystemFunctions.RTRIM, new Expression[] {string});
+ FunctionDescriptor descriptor = funcLibrary.findFunction(SourceSystemFunctions.RTRIM, new Class[] { DataTypeManager.DefaultDataClasses.STRING });
+ function.setFunctionDescriptor(descriptor);
+ function.setType(DataTypeManager.DefaultDataClasses.STRING);
+ }
+ }
+ break;
}
+ }
}
Expression[] args = function.getArgs();
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 2011-08-04 12:09:55 UTC (rev 3358)
+++ trunk/engine/src/main/java/org/teiid/query/sql/visitor/SQLStringVisitor.java 2011-08-04 14:50:37 UTC (rev 3359)
@@ -1304,6 +1304,20 @@
outputDisplayName((String)((Constant)args[0]).getValue());
registerNodes(args, 1);
append(")"); //$NON-NLS-1$
+ } else if (name.equalsIgnoreCase(SourceSystemFunctions.TRIM)) {
+ append(name);
+ append(SQLConstants.Tokens.LPAREN);
+ String value = (String)((Constant)args[0]).getValue();
+ if (!value.equalsIgnoreCase(BOTH)) {
+ append(((Constant)args[0]).getValue());
+ append(" "); //$NON-NLS-1$
+ }
+ append(args[1]);
+ append(" "); //$NON-NLS-1$
+ append(FROM);
+ append(" "); //$NON-NLS-1$
+ append(args[2]);
+ append(")"); //$NON-NLS-1$
} else {
append(name);
append("("); //$NON-NLS-1$
Modified: trunk/engine/src/main/javacc/org/teiid/query/parser/SQLParser.jj
===================================================================
--- trunk/engine/src/main/javacc/org/teiid/query/parser/SQLParser.jj 2011-08-04 12:09:55 UTC (rev 3358)
+++ trunk/engine/src/main/javacc/org/teiid/query/parser/SQLParser.jj 2011-08-04 14:50:37 UTC (rev 3359)
@@ -3548,16 +3548,14 @@
expression = expression(info)
{
args.add(expression);
- expression = null;
}
<COMMA>
expression = dataType()
{
args.add(expression);
- expression = null;
}
<RPAREN>
- )
+ )
|
(
funcToken = <CAST>
@@ -3565,30 +3563,83 @@
expression = expression(info)
{
args.add(expression);
- expression = null;
}
<AS>
expression = dataType()
{
args.add(expression);
- expression = null;
}
<RPAREN>
)
|
+ LOOKAHEAD(4, {getToken(1).image.equalsIgnoreCase("SUBSTRING")}) (
+ funcName = nonReserved("SUBSTRING")
+ <LPAREN>
+ expression = expression(info)
+ {
+ args.add(expression);
+ }
+ <FROM> expression = expression(info)
+ {
+ args.add(expression);
+ }
+ [<FOR> expression = expression(info)
+ {
+ args.add(expression);
+ }
+ ]
+ <RPAREN>
+ )
+ |
+ LOOKAHEAD(1, {getToken(1).image.equalsIgnoreCase("TRIM")}) (
+ funcName= nonReserved("TRIM")
+ <LPAREN>
+ { funcToken = null; expression = null;}
+ [
+ LOOKAHEAD(2) (((funcToken = <LEADING>|
+ funcToken = <TRAILING>|
+ funcToken = <BOTH>)
+ [expression = expression(info)])
+ |
+ expression = expression(info))
+ <FROM>
+ ]
+ {
+ if (funcToken == null) {
+ args.add(new Constant("BOTH"));
+ } else {
+ args.add(new Constant(funcToken.image));
+ }
+ if (expression == null) {
+ args.add(new Constant(" "));
+ } else {
+ if (expression instanceof Constant) {
+ Object value = ((Constant)expression).getValue();
+ if (value instanceof String && ((String)value).length() != 1) {
+ throw new ParseException(QueryPlugin.Util.getString("SQLParser.Invalid_char", "TRIM CHAR", value)); //$NON-NLS-1$
+ }
+ }
+ args.add(expression);
+ }
+ }
+ expression = expression(info)
+ {
+ args.add(expression);
+ }
+ <RPAREN>
+ )
+ |
LOOKAHEAD(<ID>, {matchesAny(getToken(1).image, "to_chars", "to_bytes") != null}) (
funcName = nonReserved("TO_CHARS", "TO_BYTES")
<LPAREN>
expression = expression(info)
{
args.add(expression);
- expression = null;
}
<COMMA>
expression = stringConstant()
{
args.add(expression);
- expression = null;
}
<RPAREN>
)
@@ -3599,19 +3650,16 @@
expression = intervalType()
{
args.add(expression);
- expression = null;
}
<COMMA>
expression = expression(info)
{
args.add(expression);
- expression = null;
}
<COMMA>
expression = expression(info)
{
args.add(expression);
- expression = null;
}
<RPAREN>
)
@@ -3654,13 +3702,11 @@
)
{
args.add(expression);
- expression = null;
}
[
<COMMA> expression = expression(info)
{
args.add(expression);
- expression = null;
}
]
<RPAREN>
@@ -3773,7 +3819,6 @@
(<COMMA> expression=expression(info)
{
content.add(expression);
- expression = null;
}
)*
<RPAREN>
@@ -3795,12 +3840,10 @@
expression = derivedColumn(info)
{
args.add(expression);
- expression = null;
}
(<COMMA> expression=derivedColumn(info)
{
args.add(expression);
- expression = null;
}
)*
<RPAREN>
@@ -3823,12 +3866,10 @@
expression = derivedColumn(info)
{
args.add(expression);
- expression = null;
}
(<COMMA> expression=derivedColumn(info)
{
args.add(expression);
- expression = null;
}
)*
<RPAREN>
Modified: trunk/engine/src/main/resources/org/teiid/query/i18n.properties
===================================================================
--- trunk/engine/src/main/resources/org/teiid/query/i18n.properties 2011-08-04 12:09:55 UTC (rev 3358)
+++ trunk/engine/src/main/resources/org/teiid/query/i18n.properties 2011-08-04 14:50:37 UTC (rev 3359)
@@ -395,6 +395,11 @@
SystemSource.Rand_result_desc=Generated Random Number
SystemSource.uuid_desc=UUID
SystemSource.uuid_result_desc=type 4 UUID
+SystemSource.trim_desc=Trim characters from the front and/or back of a string
+SystemSource.trim_arg1=Trim specification, can be one of TRAILING, LEADING, or BOTH
+SystemSource.trim_arg2=Trim character - must be a single character
+SystemSource.trim_arg3=String to trim
+SystemSource.trim_result=Trimmed string
SystemSource.Double_arg2=Number
SystemSource.Atan_arg1=Number parameter1
SystemSource.Atan_arg2=Number parameter2
Modified: trunk/engine/src/test/java/org/teiid/query/function/TestFunctionLibrary.java
===================================================================
--- trunk/engine/src/test/java/org/teiid/query/function/TestFunctionLibrary.java 2011-08-04 12:09:55 UTC (rev 3358)
+++ trunk/engine/src/test/java/org/teiid/query/function/TestFunctionLibrary.java 2011-08-04 14:50:37 UTC (rev 3359)
@@ -1408,4 +1408,16 @@
assertEquals(1, helpInvokeMethod("array_get", new Class<?>[] {DefaultDataClasses.OBJECT, DefaultDataClasses.INTEGER}, new Object[] {new Object[] {1}, 1}, null)); //$NON-NLS-1$
}
+ @Test() public void testTrim() throws Exception {
+ helpInvokeMethod("trim", new Object[] {"leading", "x", "xaxx"}, "axx"); //$NON-NLS-1$
+ }
+
+ @Test() public void testTrim1() throws Exception {
+ helpInvokeMethod("trim", new Object[] {"both", " ", " a "}, "a"); //$NON-NLS-1$
+ }
+
+ @Test() public void testTrim2() throws Exception {
+ helpInvokeMethod("trim", new Object[] {"trailing", "x", "xaxx"}, "xa"); //$NON-NLS-1$
+ }
+
}
Modified: trunk/engine/src/test/java/org/teiid/query/parser/TestParser.java
===================================================================
--- trunk/engine/src/test/java/org/teiid/query/parser/TestParser.java 2011-08-04 12:09:55 UTC (rev 3358)
+++ trunk/engine/src/test/java/org/teiid/query/parser/TestParser.java 2011-08-04 14:50:37 UTC (rev 3359)
@@ -6859,5 +6859,9 @@
query.setFrom(new From(Arrays.asList(new UnaryFromClause(new GroupSymbol("g")))));
helpTest(sql, "SELECT ROW_NUMBER() OVER (PARTITION BY x ORDER BY y) FROM g", query);
}
+
+ @Test public void testTrim1() {
+ helpException("select trim('xy' from e1) from pm1.g1");
+ }
}
Modified: trunk/engine/src/test/java/org/teiid/query/processor/eval/TestExpressionEvaluator.java
===================================================================
--- trunk/engine/src/test/java/org/teiid/query/processor/eval/TestExpressionEvaluator.java 2011-08-04 12:09:55 UTC (rev 3358)
+++ trunk/engine/src/test/java/org/teiid/query/processor/eval/TestExpressionEvaluator.java 2011-08-04 14:50:37 UTC (rev 3359)
@@ -432,4 +432,9 @@
assertEquals(Boolean.TRUE, Evaluator.evaluate(inc));
}
+ @Test public void testSubstring() throws Exception {
+ Expression ex = TestFunctionResolving.getExpression("substring('abcd' from 2 for 2)");
+ assertEquals("bc", Evaluator.evaluate(ex));
+ }
+
}
Modified: trunk/engine/src/test/java/org/teiid/query/resolver/TestResolver.java
===================================================================
--- trunk/engine/src/test/java/org/teiid/query/resolver/TestResolver.java 2011-08-04 12:09:55 UTC (rev 3358)
+++ trunk/engine/src/test/java/org/teiid/query/resolver/TestResolver.java 2011-08-04 14:50:37 UTC (rev 3359)
@@ -2977,4 +2977,14 @@
helpResolveUpdateProcedure(procedure, userQuery);
}
+
+ @Test public void testTrim() {
+ Query query = (Query)helpResolve("select trim(e1) from pm1.g1");
+ assertEquals(DataTypeManager.DefaultDataClasses.STRING, query.getProjectedSymbols().get(0).getType());
+ }
+
+ @Test public void testTrim1() {
+ helpResolve("select trim('x' from e1) from pm1.g1");
+ }
+
}
\ No newline at end of file
Modified: trunk/engine/src/test/java/org/teiid/query/rewriter/TestQueryRewriter.java
===================================================================
--- trunk/engine/src/test/java/org/teiid/query/rewriter/TestQueryRewriter.java 2011-08-04 12:09:55 UTC (rev 3358)
+++ trunk/engine/src/test/java/org/teiid/query/rewriter/TestQueryRewriter.java 2011-08-04 14:50:37 UTC (rev 3359)
@@ -2464,4 +2464,12 @@
helpTestRewriteCommand("select max(1) from pm1.g1 group by e1", "SELECT 1 FROM pm1.g1 GROUP BY e1");
}
+ @Test public void testRewriteTrim() throws Exception {
+ helpTestRewriteExpression("trim(pm1.g1.e1)", "rtrim(ltrim(pm1.g1.e1))", RealMetadataFactory.example1Cached());
+ }
+
+ @Test public void testRewriteTrim1() throws Exception {
+ helpTestRewriteExpression("trim(leading from pm1.g1.e1)", "ltrim(pm1.g1.e1)", RealMetadataFactory.example1Cached());
+ }
+
}
Modified: trunk/test-integration/common/src/test/java/org/teiid/connector/visitor/util/TestSQLStringVisitor.java
===================================================================
--- trunk/test-integration/common/src/test/java/org/teiid/connector/visitor/util/TestSQLStringVisitor.java 2011-08-04 12:09:55 UTC (rev 3358)
+++ trunk/test-integration/common/src/test/java/org/teiid/connector/visitor/util/TestSQLStringVisitor.java 2011-08-04 14:50:37 UTC (rev 3359)
@@ -432,5 +432,12 @@
Command command = FakeTranslationFactory.getInstance().getBQTTranslationUtility().parseCommand(sql, true, true);
assertEquals("SELECT MAX(g_0.IntNum) OVER (ORDER BY g_0.IntKey NULLS FIRST) FROM SmallA AS g_0", command.toString()); //$NON-NLS-1$
}
+
+ @Test public void testTrim() throws Exception {
+ String sql = "select trim(both 'x' from stringkey) from bqt1.smalla";
+
+ Command command = FakeTranslationFactory.getInstance().getBQTTranslationUtility().parseCommand(sql, true, true);
+ assertEquals("SELECT trim('x' FROM g_0.StringKey) FROM SmallA AS g_0", command.toString()); //$NON-NLS-1$
+ }
}
14 years, 8 months
teiid SVN: r3358 - in branches/7.4.x/connectors/translator-jdbc/src: main/java/org/teiid/translator/jdbc/netezza and 3 other directories.
by teiid-commits@lists.jboss.org
Author: rareddy
Date: 2011-08-04 08:09:55 -0400 (Thu, 04 Aug 2011)
New Revision: 3358
Added:
branches/7.4.x/connectors/translator-jdbc/src/main/java/org/teiid/translator/jdbc/netezza/
branches/7.4.x/connectors/translator-jdbc/src/main/java/org/teiid/translator/jdbc/netezza/NetezzaExecutionFactory.java
branches/7.4.x/connectors/translator-jdbc/src/test/java/org/teiid/translator/jdbc/netezza/
branches/7.4.x/connectors/translator-jdbc/src/test/java/org/teiid/translator/jdbc/netezza/TestNetezzaConvertModifier.java
branches/7.4.x/connectors/translator-jdbc/src/test/java/org/teiid/translator/jdbc/netezza/TestNetezzaTranslatorCapabilities.java
branches/7.4.x/connectors/translator-jdbc/src/test/java/org/teiid/translator/jdbc/netezza/TestNetezzaTranslatorDatetimeConversion.java
branches/7.4.x/connectors/translator-jdbc/src/test/java/org/teiid/translator/jdbc/netezza/TestNetezzaTranslatorSourceSystemFunctions.java
branches/7.4.x/connectors/translator-jdbc/src/test/java/org/teiid/translator/jdbc/netezza/TestNetezzaTranslatorTypeMapping.java
branches/7.4.x/connectors/translator-jdbc/src/test/java/org/teiid/translator/jdbc/netezza/TestSubstringFunctionModifier.java
Modified:
branches/7.4.x/connectors/translator-jdbc/src/main/resources/META-INF/jboss-beans.xml
Log:
TEIID-1617: Adding initial version of Netezza translator.
Added: branches/7.4.x/connectors/translator-jdbc/src/main/java/org/teiid/translator/jdbc/netezza/NetezzaExecutionFactory.java
===================================================================
--- branches/7.4.x/connectors/translator-jdbc/src/main/java/org/teiid/translator/jdbc/netezza/NetezzaExecutionFactory.java (rev 0)
+++ branches/7.4.x/connectors/translator-jdbc/src/main/java/org/teiid/translator/jdbc/netezza/NetezzaExecutionFactory.java 2011-08-04 12:09:55 UTC (rev 3358)
@@ -0,0 +1,382 @@
+/*
+ * 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.translator.jdbc.netezza;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import org.teiid.language.Expression;
+import org.teiid.language.Function;
+import org.teiid.language.Limit;
+import org.teiid.translator.ExecutionContext;
+import org.teiid.translator.SourceSystemFunctions;
+import org.teiid.translator.Translator;
+import org.teiid.translator.TranslatorException;
+import org.teiid.translator.jdbc.AliasModifier;
+import org.teiid.translator.jdbc.ConvertModifier;
+import org.teiid.translator.jdbc.ExtractFunctionModifier;
+import org.teiid.translator.jdbc.FunctionModifier;
+import org.teiid.translator.jdbc.JDBCExecutionFactory;
+import org.teiid.translator.jdbc.LocateFunctionModifier;
+
+
+@Translator(name = "netezza", description = "A translator for Netezza Database")
+public class NetezzaExecutionFactory extends JDBCExecutionFactory {
+
+ private static final String TIME_FORMAT = "HH24:MI:SS";
+ private static final String DATE_FORMAT = "YYYY-MM-DD";
+ private static final String DATETIME_FORMAT = DATE_FORMAT + " " + TIME_FORMAT;
+ private static final String TIMESTAMP_FORMAT = DATETIME_FORMAT + ".MS";
+
+ public NetezzaExecutionFactory() {
+ setSupportsFullOuterJoins(true);
+ setSupportsOrderBy(true);
+ setSupportsOuterJoins(true);
+ setSupportsSelectDistinct(true);
+ setSupportsInnerJoins(true);
+ }
+
+ public void start() throws TranslatorException {
+ super.start();
+
+ //STRING FUNCTION MODIFIERS
+ ////////////////////////////////////
+ registerFunctionModifier(SourceSystemFunctions.CHAR, new AliasModifier("chr"));
+ registerFunctionModifier(SourceSystemFunctions.LCASE,new AliasModifier("lower"));
+ registerFunctionModifier(SourceSystemFunctions.UCASE,new AliasModifier("upper"));
+ registerFunctionModifier(SourceSystemFunctions.LOCATE, new LocateFunctionModifier(getLanguageFactory(), "INSTR", true));
+ registerFunctionModifier(SourceSystemFunctions.CONCAT, new AliasModifier("||"));
+ ///NUMERIC FUNCTION MODIFIERS
+ ////////////////////////////////////
+ registerFunctionModifier(SourceSystemFunctions.CEILING, new AliasModifier("ceil"));
+ registerFunctionModifier(SourceSystemFunctions.POWER, new AliasModifier("pow"));
+ registerFunctionModifier(SourceSystemFunctions.LOG, new AliasModifier("LN"));
+ ///BIT FUNCTION MODIFIERS
+ ////////////////////////////////////
+ registerFunctionModifier(SourceSystemFunctions.BITAND, new AliasModifier("intNand"));
+ registerFunctionModifier(SourceSystemFunctions.BITNOT, new AliasModifier("intNnot"));
+ registerFunctionModifier(SourceSystemFunctions.BITOR, new AliasModifier("intNor"));
+ registerFunctionModifier(SourceSystemFunctions.BITXOR, new AliasModifier("intNxor"));
+ //DATE FUNCTION MODIFIERS
+ //////////////////////////////////////////
+ registerFunctionModifier(SourceSystemFunctions.YEAR, new ExtractFunctionModifier());
+ registerFunctionModifier(SourceSystemFunctions.DAYOFYEAR, new ExtractModifier("DOY"));
+ registerFunctionModifier(SourceSystemFunctions.QUARTER, new ExtractFunctionModifier());
+ registerFunctionModifier(SourceSystemFunctions.MONTH, new ExtractFunctionModifier());
+ registerFunctionModifier(SourceSystemFunctions.DAYOFMONTH, new ExtractModifier("DAY"));
+ registerFunctionModifier(SourceSystemFunctions.WEEK, new ExtractFunctionModifier());
+ registerFunctionModifier(SourceSystemFunctions.DAYOFWEEK, new ExtractModifier("DOW"));
+ registerFunctionModifier(SourceSystemFunctions.HOUR, new ExtractFunctionModifier());
+ registerFunctionModifier(SourceSystemFunctions.MINUTE, new ExtractFunctionModifier());
+ registerFunctionModifier(SourceSystemFunctions.SECOND, new ExtractFunctionModifier());
+ registerFunctionModifier(SourceSystemFunctions.CURDATE, new AliasModifier("CURRENT_DATE"));
+ registerFunctionModifier(SourceSystemFunctions.CURTIME, new AliasModifier("CURRENT_TIME"));
+ //SYSTEM FUNCTIONS
+ ////////////////////////////////////
+ registerFunctionModifier(SourceSystemFunctions.IFNULL,new AliasModifier("NVL"));
+
+
+ // DATA TYPE CONVERSION
+ ///////////////////////////////////////////
+ ConvertModifier convertModifier = new ConvertModifier();
+ convertModifier.addTypeMapping("char(1)", FunctionModifier.CHAR);
+ convertModifier.addTypeMapping("byteint", FunctionModifier.BYTE);
+ convertModifier.addTypeMapping("smallint", FunctionModifier.SHORT);
+ convertModifier.addTypeMapping("bigint", FunctionModifier.LONG);
+ convertModifier.addTypeMapping("numeric(38)", FunctionModifier.BIGINTEGER);
+ convertModifier.addTypeMapping("numeric(38,18)", FunctionModifier.BIGDECIMAL);
+ convertModifier.addTypeMapping("varchar(4000)", FunctionModifier.STRING);
+ //convertModifier.addTypeMapping("nvarchar(5)", FunctionModifier.BOOLEAN);
+
+ ///NO BOOLEAN, INTEGER, FLOAT, DATE, TIME, TIMESTAMP, as they are directly available in netezza
+ ///NO NULL, CLOB, BLOB, OBJECT, XML
+
+
+ ///BOOLEAN--BYTE, SHORT, INTEGER, LONG, FLOAT, DOUBLE, BIGINTEGER, BIGDECIMAL--AS IT DOESN'T WORK IMPLICITLY IN NETEZZA
+
+ convertModifier.addConvert(FunctionModifier.BOOLEAN, FunctionModifier.INTEGER, new BooleanToNumericConversionModifier());
+ convertModifier.addConvert(FunctionModifier.BOOLEAN, FunctionModifier.BYTE, new BooleanToNumericConversionModifier());
+ convertModifier.addConvert(FunctionModifier.BOOLEAN, FunctionModifier.SHORT, new BooleanToNumericConversionModifier());
+ convertModifier.addConvert(FunctionModifier.BOOLEAN, FunctionModifier.LONG, new BooleanToNumericConversionModifier());
+ convertModifier.addConvert(FunctionModifier.BOOLEAN, FunctionModifier.FLOAT, new BooleanToNumericConversionModifier());
+ convertModifier.addConvert(FunctionModifier.BOOLEAN, FunctionModifier.DOUBLE, new BooleanToNumericConversionModifier());
+ convertModifier.addConvert(FunctionModifier.BOOLEAN, FunctionModifier.BIGINTEGER, new BooleanToNumericConversionModifier());
+ convertModifier.addConvert(FunctionModifier.BOOLEAN, FunctionModifier.BIGDECIMAL, new BooleanToNumericConversionModifier());
+ convertModifier.addConvert(FunctionModifier.BOOLEAN, FunctionModifier.STRING, new BooleanToStringConversionModifier());
+ convertModifier.addConvert(FunctionModifier.STRING, FunctionModifier.BOOLEAN, new FunctionModifier() {
+ @Override
+ public List<?> translate(Function function) {
+ Expression stringValue = function.getParameters().get(0);
+ return Arrays.asList("CASE WHEN ", stringValue, " IN ('false', '0') THEN '0' WHEN ", stringValue, " IS NOT NULL THEN '1' END");
+ }
+ });
+ convertModifier.addTypeConversion(new FunctionModifier() {
+ @Override
+ public List<?> translate(Function function) {
+ Expression stringValue = function.getParameters().get(0);
+ return Arrays.asList("CASE WHEN ", stringValue, " = 0 THEN '0' WHEN ", stringValue, " IS NOT NULL THEN '1' END");
+ }
+ }, FunctionModifier.BOOLEAN);
+
+
+
+
+ ////////STRING TO DATATYPE CONVERSION OTHER THAN DATE/TIME
+ convertModifier.addConvert(FunctionModifier.STRING, FunctionModifier.INTEGER, new CastModifier("integer"));
+ convertModifier.addConvert(FunctionModifier.STRING, FunctionModifier.FLOAT, new CastModifier("float"));
+ convertModifier.addConvert(FunctionModifier.STRING, FunctionModifier.DOUBLE, new CastModifier("double"));
+ ///// STRING --> CHAR, BYTE, SHORT, LONG, BIGI, BIGD, BOOLEAN is taken care by Type Mapping
+ ///// NO conversion support for NULL, CLOB, BLOB, OBJECT, XML
+ ////STRING TO DATE/TIME CONVERSION////
+ //////////////////////////////////////
+ convertModifier.addConvert(FunctionModifier.STRING, FunctionModifier.DATE, new ConvertModifier.FormatModifier("to_date", DATE_FORMAT));
+ convertModifier.addConvert(FunctionModifier.STRING, FunctionModifier.TIME, new ConvertModifier.FormatModifier("to_timestamp", TIME_FORMAT));
+ convertModifier.addConvert(FunctionModifier.STRING, FunctionModifier.TIMESTAMP, new ConvertModifier.FormatModifier("to_timestamp", TIMESTAMP_FORMAT));
+ //////DATE/TIME INTERNAL CONVERSION/////////
+ convertModifier.addConvert(FunctionModifier.TIMESTAMP, FunctionModifier.TIME, new CastModifier("TIME"));
+ convertModifier.addConvert(FunctionModifier.TIMESTAMP, FunctionModifier.DATE, new CastModifier("DATE"));
+ convertModifier.addConvert(FunctionModifier.DATE, FunctionModifier.TIMESTAMP, new CastModifier("TIMESTAMP"));
+ //convertModifier.addConvert(FunctionModifier.TIME, FunctionModifier.TIMESTAMP, new CastModifier("TIMESTAMP")); //TIME --> TIMESTAMP --DOESN't WORK IN NETEZZA-NO FUNCTION SUPPORT
+
+ ////DATE/TIME to STRING CONVERION////
+ /////////////////////////////////////
+ convertModifier.addConvert(FunctionModifier.TIMESTAMP, FunctionModifier.STRING, new ConvertModifier.FormatModifier("to_char", TIMESTAMP_FORMAT));
+ ///NO NETEZAA FUNCTION for DATE, TIME to STRING
+
+
+ convertModifier.setWideningNumericImplicit(true);
+ registerFunctionModifier(SourceSystemFunctions.CONVERT, convertModifier);
+ }
+
+ @Override
+ public List<String> getSupportedFunctions() {
+ List<String> supportedFunctions = new ArrayList<String>();
+ supportedFunctions.addAll(super.getSupportedFunctions());
+
+ ////////////////////////////////////////////////////////////
+ //STRING FUNCTIONS
+ //////////////////////////////////////////////////////////
+ supportedFunctions.add(SourceSystemFunctions.ASCII);// taken care with alias function modifier
+ supportedFunctions.add(SourceSystemFunctions.CHAR);//ALIAS to use 'chr'
+ supportedFunctions.add(SourceSystemFunctions.CONCAT); // ALIAS ||
+ supportedFunctions.add(SourceSystemFunctions.INITCAP);
+ supportedFunctions.add(SourceSystemFunctions.LCASE);//ALIAS 'lower'
+ supportedFunctions.add(SourceSystemFunctions.LPAD);
+ supportedFunctions.add(SourceSystemFunctions.LENGTH);
+ supportedFunctions.add(SourceSystemFunctions.LOCATE); //LOCATE FUNCTIO MODIFIER
+ supportedFunctions.add(SourceSystemFunctions.LTRIM);
+ //supportedFunctions.add(SourceSystemFunctions.REPEAT);
+ supportedFunctions.add(SourceSystemFunctions.RPAD);
+ supportedFunctions.add(SourceSystemFunctions.RTRIM);
+ supportedFunctions.add(SourceSystemFunctions.SUBSTRING); //No Need of ALIAS as both substring and substr work in netezza
+ supportedFunctions.add(SourceSystemFunctions.UCASE); //ALIAS UPPER
+ // FUNCTION DIFFERENCE = "difference"; ///NO FUNCTION FOUND--DIFFERENCE
+ // FUNCTION INSERT = "insert";
+ // supportedFunctions.add(SourceSystemFunctions.LEFT); //is this available or is it simply for LEFT OUTER JOIN?
+ // FUNCTION REPLACE = "replace"; // NO REPLACE Function
+ // supportedFunctions.add(SourceSystemFunctions.RIGHT);--is this available or is it simply for RIGHT OUTER JOIN?
+ // FUNCTION SOUNDEX = "soundex";
+ // FUNCTION TO_BYTES = "to_bytes";
+ // FUNCTION TO_CHARS = "to_chars";
+ ////////// ////////////////////////////////////////////////////////////////////
+ //NUMERIC FUNCTIONS////////////////////////////////////////////////////////////
+ //////////////////////////////////////////////////////////////////////////////
+ //supportedFunctions.add(SourceSystemFunctions.ABS);
+ supportedFunctions.add(SourceSystemFunctions.ACOS);
+ supportedFunctions.add(SourceSystemFunctions.ASIN);
+ supportedFunctions.add(SourceSystemFunctions.ATAN);
+ supportedFunctions.add(SourceSystemFunctions.ATAN2);
+ supportedFunctions.add(SourceSystemFunctions.CEILING); ///ALIAS-ceil
+ supportedFunctions.add(SourceSystemFunctions.COS);
+ supportedFunctions.add(SourceSystemFunctions.COT);
+ supportedFunctions.add(SourceSystemFunctions.DEGREES);
+ //supportedFunctions.add(SourceSystemFunctions.EXP);
+ supportedFunctions.add(SourceSystemFunctions.FLOOR);
+ supportedFunctions.add(SourceSystemFunctions.LOG);
+ supportedFunctions.add(SourceSystemFunctions.MOD);
+ supportedFunctions.add(SourceSystemFunctions.PI);
+ supportedFunctions.add(SourceSystemFunctions.POWER);// ALIAS-POW
+ supportedFunctions.add(SourceSystemFunctions.RADIANS);
+ supportedFunctions.add(SourceSystemFunctions.ROUND);
+ supportedFunctions.add(SourceSystemFunctions.SIGN);
+ supportedFunctions.add(SourceSystemFunctions.SIN);
+ supportedFunctions.add(SourceSystemFunctions.SQRT);
+ supportedFunctions.add(SourceSystemFunctions.TAN);
+ // FUNCTION TRANSLATE = "translate";
+ // FUNCTION TRUNCATE = "truncate";
+ // FUNCTION FORMATINTEGER = "formatinteger";
+ // FUNCTION FORMATLONG = "formatlong";
+ // FUNCTION FORMATDOUBLE = "formatdouble";
+ // FUNCTION FORMATFLOAT = "formatfloat";
+ // FUNCTION FORMATBIGINTEGER = "formatbiginteger";
+ // FUNCTION FORMATBIGDECIMAL = "formatbigdecimal";
+ // FUNCTION LOG10 = "log10";
+ // FUNCTION PARSEINTEGER = "parseinteger";
+ // FUNCTION PARSELONG = "parselong";
+ // FUNCTION PARSEDOUBLE = "parsedouble";
+ // FUNCTION PARSEFLOAT = "parsefloat";
+ // FUNCTION PARSEBIGINTEGER = "parsebiginteger";
+ // FUNCTION PARSEBIGDECIMAL = "parsebigdecimal";
+ // supportedFunctions.add(SourceSystemFunctions.RAND); --Needs Alias--But, is it required to even have an alias???
+ /////////////////////////////////////////////////////////////////////
+ //BIT FUNCTIONS//////////////////////////////////////////////////////
+ //ALIAS FUNCTION MODIFIER IS APPLIED//////////////////////////////
+ supportedFunctions.add(SourceSystemFunctions.BITAND);
+ supportedFunctions.add(SourceSystemFunctions.BITOR);
+ supportedFunctions.add(SourceSystemFunctions.BITNOT);
+ supportedFunctions.add(SourceSystemFunctions.BITXOR);
+ // DATE FUNCTIONS
+ supportedFunctions.add(SourceSystemFunctions.CURDATE);
+ supportedFunctions.add(SourceSystemFunctions.CURTIME);
+ supportedFunctions.add(SourceSystemFunctions.DAYOFMONTH);
+ supportedFunctions.add(SourceSystemFunctions.DAYOFYEAR);
+ supportedFunctions.add(SourceSystemFunctions.DAYOFWEEK);
+ supportedFunctions.add(SourceSystemFunctions.HOUR);
+ supportedFunctions.add(SourceSystemFunctions.MINUTE);
+ supportedFunctions.add(SourceSystemFunctions.MONTH);
+ supportedFunctions.add(SourceSystemFunctions.QUARTER);
+ supportedFunctions.add(SourceSystemFunctions.SECOND);
+ supportedFunctions.add(SourceSystemFunctions.WEEK);
+ supportedFunctions.add(SourceSystemFunctions.YEAR);
+ // FUNCTION DAYNAME = "dayname";
+ // FUNCTION FORMATTIMESTAMP = "formattimestamp";
+ // FUNCTION MODIFYTIMEZONE = "modifytimezone";
+ // FUNCTION MONTHNAME = "monthname";
+ // FUNCTION NOW = "now";
+ // FUNCTION PARSETIMESTAMP = "parsetimestamp";
+ // FUNCTION TIMESTAMPADD = "timestampadd";
+ // FUNCTION TIMESTAMPCREATE = "timestampcreate";
+ // FUNCTION TIMESTAMPDIFF = "timestampdiff";
+
+
+ //SYSTEM FUNCTIONS
+ supportedFunctions.add(SourceSystemFunctions.IFNULL); //ALIAS-NVL
+ supportedFunctions.add(SourceSystemFunctions.COALESCE);
+ supportedFunctions.add(SourceSystemFunctions.NULLIF);
+
+
+ //CONVERSION functions
+ supportedFunctions.add(SourceSystemFunctions.CONVERT);
+
+
+ return supportedFunctions;
+ }
+
+ public static class ExtractModifier extends FunctionModifier {
+ private String type;
+ public ExtractModifier(String type) {
+ this.type = type;
+ }
+ @Override
+ public List<?> translate(Function function) {
+ return Arrays.asList("extract(",this.type," from ",function.getParameters().get(0) ,")");
+ }
+ }
+
+ public static class BooleanToNumericConversionModifier extends FunctionModifier {
+ @Override
+ public List<?> translate(Function function) {
+ Expression booleanValue = function.getParameters().get(0);
+ if (booleanValue instanceof Function) {
+ Function nested = (Function)booleanValue;
+ if (nested.getName().equalsIgnoreCase("convert") && Number.class.isAssignableFrom(nested.getParameters().get(0).getType())) {
+ booleanValue = nested.getParameters().get(0);
+ }
+ }
+ return Arrays.asList("(CASE WHEN ", booleanValue, " IN ( '0', 'FALSE') THEN 0 WHEN ", booleanValue, " IS NOT NULL THEN 1 END)");
+ }
+
+ }
+ public static class BooleanToStringConversionModifier extends FunctionModifier {
+ @Override
+ public List<?> translate(Function function) {
+ Expression booleanValue = function.getParameters().get(0);
+ if (booleanValue instanceof Function) {
+ Function nested = (Function)booleanValue;
+ if (nested.getName().equalsIgnoreCase("convert") && Number.class.isAssignableFrom(nested.getParameters().get(0).getType())) {
+ booleanValue = nested.getParameters().get(0);
+ }
+ }
+ return Arrays.asList("CASE WHEN ", booleanValue, " = '0' THEN 'false' WHEN ", booleanValue, " IS NOT NULL THEN 'true' END");
+ }
+
+ }
+
+
+ public static class CastModifier extends FunctionModifier {
+ private String target;
+ public CastModifier(String target) {
+ this.target = target;
+ }
+ @Override
+ public List<?> translate(Function function) {
+ return Arrays.asList("cast(", function.getParameters().get(0), " AS "+this.target+")");
+ }
+ }
+
+
+ @Override
+ public List<?> translateLimit(Limit limit, ExecutionContext context) {
+ if (limit.getRowOffset() > 0) {
+ return Arrays.asList("LIMIT ", limit.getRowLimit(), " OFFSET ", limit.getRowOffset());
+ }
+ return null;
+ }
+
+ @Override
+ public boolean supportsCorrelatedSubqueries() {
+ return false;
+ }
+
+ @Override
+ public boolean supportsIntersect() {
+ return true;
+ }
+
+ @Override
+ public boolean supportsExcept() {
+ return true;
+ }
+
+ @Override
+ public boolean supportsInlineViews() {
+ return true;
+ }
+
+ @Override
+ public boolean supportsRowLimit() {
+ return true;
+ }
+
+ @Override
+ public boolean supportsRowOffset() {
+ return true;
+ }
+
+ @Override
+ public boolean supportsAggregatesEnhancedNumeric() {
+ return true;
+ }
+
+}
Property changes on: branches/7.4.x/connectors/translator-jdbc/src/main/java/org/teiid/translator/jdbc/netezza/NetezzaExecutionFactory.java
___________________________________________________________________
Added: svn:mime-type
+ text/plain
Modified: branches/7.4.x/connectors/translator-jdbc/src/main/resources/META-INF/jboss-beans.xml
===================================================================
--- branches/7.4.x/connectors/translator-jdbc/src/main/resources/META-INF/jboss-beans.xml 2011-08-03 15:13:06 UTC (rev 3357)
+++ branches/7.4.x/connectors/translator-jdbc/src/main/resources/META-INF/jboss-beans.xml 2011-08-04 12:09:55 UTC (rev 3358)
@@ -335,5 +335,21 @@
<parameter class="java.lang.String">translator-intersystems-cache</parameter>
<parameter class="java.lang.String">InterSystems Cache</parameter>
</constructor>
- </bean>
+ </bean>
+
+ <!-- Netezza -->
+ <bean name="translator-neteza-template" class="org.teiid.templates.TranslatorDeploymentTemplate">
+ <property name="info"><inject bean="translator-netezza" /> </property>
+ <property name="managedObjectFactory"> <inject bean="ManagedObjectFactory" /> </property>
+ </bean>
+
+ <bean name="translator-netezza" class="org.teiid.templates.TranslatorTemplateInfo">
+ <constructor factoryMethod="createTemplateInfo">
+ <factory bean="TranslatorDeploymentTemplateInfoFactory" />
+ <parameter class="java.lang.Class">org.teiid.templates.TranslatorTemplateInfo</parameter>
+ <parameter class="java.lang.Class">org.teiid.translator.jdbc.netezza.NetezzaExecutionFactory</parameter>
+ <parameter class="java.lang.String">translator-netezza</parameter>
+ <parameter class="java.lang.String">Netezza</parameter>
+ </constructor>
+ </bean>
</deployment>
\ No newline at end of file
Added: branches/7.4.x/connectors/translator-jdbc/src/test/java/org/teiid/translator/jdbc/netezza/TestNetezzaConvertModifier.java
===================================================================
--- branches/7.4.x/connectors/translator-jdbc/src/test/java/org/teiid/translator/jdbc/netezza/TestNetezzaConvertModifier.java (rev 0)
+++ branches/7.4.x/connectors/translator-jdbc/src/test/java/org/teiid/translator/jdbc/netezza/TestNetezzaConvertModifier.java 2011-08-04 12:09:55 UTC (rev 3358)
@@ -0,0 +1,509 @@
+/*
+ * 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.translator.jdbc.netezza;
+
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.util.Arrays;
+
+import junit.framework.TestCase;
+
+import org.teiid.language.Expression;
+import org.teiid.language.Function;
+import org.teiid.language.LanguageFactory;
+import org.teiid.translator.TypeFacility;
+import org.teiid.translator.jdbc.SQLConversionVisitor;
+
+
+/**
+ */
+public class TestNetezzaConvertModifier extends TestCase {
+
+ private static final LanguageFactory LANG_FACTORY = new LanguageFactory();
+
+ public TestNetezzaConvertModifier(String name) {
+ super(name);
+ }
+
+ public String helpGetString(Expression expr) throws Exception {
+ NetezzaExecutionFactory trans = new NetezzaExecutionFactory();
+ trans.start();
+ SQLConversionVisitor sqlVisitor = trans.getSQLConversionVisitor();
+ sqlVisitor.append(expr);
+
+ return sqlVisitor.toString();
+ }
+
+ public void helpTest(Expression srcExpression, String tgtType, String expectedExpression) throws Exception {
+ Function func = LANG_FACTORY.createFunction("convert", //$NON-NLS-1$
+ Arrays.asList(
+ srcExpression,
+ LANG_FACTORY.createLiteral(tgtType, String.class)),
+ TypeFacility.getDataTypeClass(tgtType));
+
+ assertEquals("Error converting from " + srcExpression.getType() + " to " + tgtType,
+ expectedExpression, helpGetString(func));
+ }
+
+
+
+
+ // Source = STRING
+ public void testStringToChar() throws Exception {
+ helpTest(LANG_FACTORY.createLiteral("5", String.class), "char", "cast('5' AS char(1))");
+ }
+
+ public void testStringToBoolean() throws Exception {
+ helpTest(LANG_FACTORY.createLiteral("5", String.class), "boolean", "CASE WHEN '5' IN ('false', '0') THEN '0' WHEN '5' IS NOT NULL THEN '1' END");
+ }
+
+ public void testStringToByte() throws Exception {
+ helpTest(LANG_FACTORY.createLiteral("5", String.class), "byte", "cast('5' AS byteint)");
+ }
+
+ public void testStringToShort() throws Exception {
+ helpTest(LANG_FACTORY.createLiteral("5", String.class), "short", "cast('5' AS smallint)");
+ }
+
+ public void testStringToInteger() throws Exception {
+ helpTest(LANG_FACTORY.createLiteral("5", String.class), "integer", "cast('5' AS integer)");
+ }
+
+ public void testStringToLong() throws Exception {
+ helpTest(LANG_FACTORY.createLiteral("5", String.class), "long", "cast('5' AS bigint)");
+ }
+
+ public void testStringToBigInteger() throws Exception {
+ helpTest(LANG_FACTORY.createLiteral("5", String.class), "biginteger", "cast('5' AS numeric(38))"); //$NON-NLS-1$//$NON-NLS-2$ //$NON-NLS-3$
+ }
+
+ public void testStringToFloat() throws Exception {
+ helpTest(LANG_FACTORY.createLiteral("5", String.class), "float", "cast('5' AS float)");
+ }
+
+ public void testStringToDouble() throws Exception {
+ helpTest(LANG_FACTORY.createLiteral("5", String.class), "double", "cast('5' AS double)");
+ }
+
+ public void testStringToDate() throws Exception {
+ helpTest(LANG_FACTORY.createLiteral("2004-06-29", String.class), "date", "to_date('2004-06-29', 'YYYY-MM-DD')");
+ }
+
+ public void testStringToTime() throws Exception {
+ helpTest(LANG_FACTORY.createLiteral("23:59:59", String.class), "time", "to_timestamp('23:59:59', 'HH24:MI:SS')");
+ }
+
+ public void testStringToTimestamp() throws Exception {
+ helpTest(LANG_FACTORY.createLiteral("2004-06-29 23:59:59.987", String.class), "timestamp", "to_timestamp('2004-06-29 23:59:59.987', 'YYYY-MM-DD HH24:MI:SS.MS')");
+ }
+
+ public void testStringToBigDecimal() throws Exception {
+ helpTest(LANG_FACTORY.createLiteral("5", String.class), "bigdecimal", "cast('5' AS numeric(38,18))");
+ }
+
+ // Source = CHAR
+
+ public void testCharToString() throws Exception {
+ helpTest(LANG_FACTORY.createLiteral(new Character('5'), Character.class), "string", "'5'");
+ }
+
+ // Source = BOOLEAN
+
+ public void testBooleanToString() throws Exception {
+ helpTest(LANG_FACTORY.createLiteral(Boolean.TRUE, Boolean.class), "string", "CASE WHEN 1 = '0' THEN 'false' WHEN 1 IS NOT NULL THEN 'true' END");
+ }
+
+ public void testBooleanToByte() throws Exception {
+ helpTest(LANG_FACTORY.createLiteral(Boolean.FALSE, Boolean.class), "byte", "(CASE WHEN 0 IN ( '0', 'FALSE') THEN 0 WHEN 0 IS NOT NULL THEN 1 END)");
+ }
+
+ public void testBooleanToShort() throws Exception {
+ helpTest(LANG_FACTORY.createLiteral(Boolean.FALSE, Boolean.class), "short", "(CASE WHEN 0 IN ( '0', 'FALSE') THEN 0 WHEN 0 IS NOT NULL THEN 1 END)");
+ }
+
+ public void testBooleanToInteger() throws Exception {
+ helpTest(LANG_FACTORY.createLiteral(Boolean.FALSE, Boolean.class), "integer", "(CASE WHEN 0 IN ( '0', 'FALSE') THEN 0 WHEN 0 IS NOT NULL THEN 1 END)");
+ }
+
+ public void testBooleanToLong() throws Exception {
+ helpTest(LANG_FACTORY.createLiteral(Boolean.FALSE, Boolean.class), "long", "(CASE WHEN 0 IN ( '0', 'FALSE') THEN 0 WHEN 0 IS NOT NULL THEN 1 END)");
+ }
+
+ public void testBooleanToBigInteger() throws Exception {
+ helpTest(LANG_FACTORY.createLiteral(Boolean.FALSE, Boolean.class), "biginteger", "(CASE WHEN 0 IN ( '0', 'FALSE') THEN 0 WHEN 0 IS NOT NULL THEN 1 END)");
+ }
+
+ public void testBooleanToFloat() throws Exception {
+ helpTest(LANG_FACTORY.createLiteral(Boolean.FALSE, Boolean.class), "float", "(CASE WHEN 0 IN ( '0', 'FALSE') THEN 0 WHEN 0 IS NOT NULL THEN 1 END)");
+ }
+
+ public void testBooleanToDouble() throws Exception {
+ helpTest(LANG_FACTORY.createLiteral(Boolean.FALSE, Boolean.class), "double", "(CASE WHEN 0 IN ( '0', 'FALSE') THEN 0 WHEN 0 IS NOT NULL THEN 1 END)");
+ }
+
+ public void testBooleanToBigDecimal() throws Exception {
+ helpTest(LANG_FACTORY.createLiteral(Boolean.FALSE, Boolean.class), "bigdecimal", "(CASE WHEN 0 IN ( '0', 'FALSE') THEN 0 WHEN 0 IS NOT NULL THEN 1 END)");
+ }
+
+ // Source = BYTE
+
+ public void testByteToString() throws Exception {
+ helpTest(LANG_FACTORY.createLiteral(new Byte((byte)1), Byte.class), "string", "cast(1 AS varchar(4000))");
+ }
+
+ public void testByteToBoolean() throws Exception {
+ helpTest(LANG_FACTORY.createLiteral(new Byte((byte)1), Byte.class), "boolean", "CASE WHEN 1 = 0 THEN '0' WHEN 1 IS NOT NULL THEN '1' END");
+ }
+
+// public void testByteToShort() throws Exception {
+// helpTest(LANG_FACTORY.createLiteral(new Byte((byte)1), Byte.class), "short", "1");
+// }
+//
+// public void testByteToInteger() throws Exception {
+// helpTest(LANG_FACTORY.createLiteral(new Byte((byte)1), Byte.class), "integer", "integer(1)");
+// }
+//
+// public void testByteToLong() throws Exception {
+// helpTest(LANG_FACTORY.createLiteral(new Byte((byte)1), Byte.class), "long", "bigint(1)");
+// }
+//
+// public void testByteToBigInteger() throws Exception {
+// helpTest(LANG_FACTORY.createLiteral(new Byte((byte)1), Byte.class), "biginteger", "cast(1 AS numeric(31,0))");
+// }
+//
+// public void testByteToFloat() throws Exception {
+// helpTest(LANG_FACTORY.createLiteral(new Byte((byte)1), Byte.class), "float", "cast(1 AS real)");
+// }
+//
+// public void testByteToDouble() throws Exception {
+// helpTest(LANG_FACTORY.createLiteral(new Byte((byte)1), Byte.class), "double", "double(1)");
+// }
+//
+// public void testByteToBigDecimal() throws Exception {
+// helpTest(LANG_FACTORY.createLiteral(new Byte((byte)1), Byte.class), "bigdecimal", "cast(1 AS numeric(31,12))");
+// }
+
+ // Source = SHORT
+
+ public void testShortToString() throws Exception {
+ helpTest(LANG_FACTORY.createLiteral(new Short((short)1), Short.class), "string", "cast(1 AS varchar(4000))");
+ }
+
+ public void testShortToBoolean() throws Exception {
+ helpTest(LANG_FACTORY.createLiteral(new Short((short)1), Short.class), "boolean", "CASE WHEN 1 = 0 THEN '0' WHEN 1 IS NOT NULL THEN '1' END");
+ }
+
+// public void testShortToByte() throws Exception {
+// helpTest(LANG_FACTORY.createLiteral(new Short((short)1), Short.class), "byte", "1");
+// }
+//
+// public void testShortToInteger() throws Exception {
+// helpTest(LANG_FACTORY.createLiteral(new Short((short)1), Short.class), "integer", "integer(1)");
+// }
+//
+// public void testShortToLong() throws Exception {
+// helpTest(LANG_FACTORY.createLiteral(new Short((short)1), Short.class), "long", "bigint(1)");
+// }
+//
+// public void testShortToBigInteger() throws Exception {
+// helpTest(LANG_FACTORY.createLiteral(new Short((short)1), Short.class), "biginteger", "cast(1 AS numeric(31,0))");
+// }
+//
+// public void testShortToFloat() throws Exception {
+// helpTest(LANG_FACTORY.createLiteral(new Short((short)1), Short.class), "float", "cast(1 AS real)");
+// }
+//
+// public void testShortToDouble() throws Exception {
+// helpTest(LANG_FACTORY.createLiteral(new Short((short)1), Short.class), "double", "double(1)");
+// }
+//
+// public void testShortToBigDecimal() throws Exception {
+// helpTest(LANG_FACTORY.createLiteral(new Short((short)1), Short.class), "bigdecimal", "cast(1 AS numeric(31,12))");
+// }
+
+ // Source = INTEGER
+
+ public void testIntegerToString() throws Exception {
+ helpTest(LANG_FACTORY.createLiteral(new Integer(1), Integer.class), "string", "cast(1 AS varchar(4000))");
+ }
+
+ public void testIntegerToBoolean() throws Exception {
+ helpTest(LANG_FACTORY.createLiteral(new Integer(1), Integer.class), "boolean", "CASE WHEN 1 = 0 THEN '0' WHEN 1 IS NOT NULL THEN '1' END");
+ }
+
+// public void testIntegerToByte() throws Exception {
+// helpTest(LANG_FACTORY.createLiteral(new Integer(1), Integer.class), "byte", "smallint(1)");
+// }
+//
+// public void testIntegerToShort() throws Exception {
+// helpTest(LANG_FACTORY.createLiteral(new Integer(1), Integer.class), "short", "smallint(1)");
+// }
+//
+// public void testIntegerToLong() throws Exception {
+// helpTest(LANG_FACTORY.createLiteral(new Integer(1), Integer.class), "long", "bigint(1)");
+// }
+//
+// public void testIntegerToBigInteger() throws Exception {
+// helpTest(LANG_FACTORY.createLiteral(new Integer(1), Integer.class), "biginteger", "cast(1 AS numeric(31,0))");
+// }
+//
+// public void testIntegerToFloat() throws Exception {
+// helpTest(LANG_FACTORY.createLiteral(new Integer(1), Integer.class), "float", "cast(1 AS real)");
+// }
+//
+// public void testIntegerToDouble() throws Exception {
+// helpTest(LANG_FACTORY.createLiteral(new Integer(1), Integer.class), "double", "double(1)");
+// }
+//
+// public void testIntegerToBigDecimal() throws Exception {
+// helpTest(LANG_FACTORY.createLiteral(new Integer(1), Integer.class), "bigdecimal", "cast(1 AS numeric(31,12))");
+// }
+
+ // Source = LONG
+
+ public void testLongToString() throws Exception {
+ helpTest(LANG_FACTORY.createLiteral(new Long(1), Long.class), "string", "cast(1 AS varchar(4000))");
+ }
+
+ public void testLongToBoolean() throws Exception {
+ helpTest(LANG_FACTORY.createLiteral(new Long(1), Long.class), "boolean", "CASE WHEN 1 = 0 THEN '0' WHEN 1 IS NOT NULL THEN '1' END");
+ }
+
+// public void testLongToByte() throws Exception {
+// helpTest(LANG_FACTORY.createLiteral(new Long(1), Long.class), "byte", "smallint(1)");
+// }
+//
+// public void testLongToShort() throws Exception {
+// helpTest(LANG_FACTORY.createLiteral(new Long(1), Long.class), "short", "smallint(1)");
+// }
+//
+// public void testLongToInteger() throws Exception {
+// helpTest(LANG_FACTORY.createLiteral(new Long(1), Long.class), "integer", "integer(1)");
+// }
+//
+// public void testLongToBigInteger() throws Exception {
+// helpTest(LANG_FACTORY.createLiteral(new Long(1), Long.class), "biginteger", "cast(1 AS numeric(31,0))");
+// }
+//
+// public void testLongToFloat() throws Exception {
+// helpTest(LANG_FACTORY.createLiteral(new Long(1), Long.class), "float", "cast(1 AS real)");
+// }
+//
+// public void testLongToDouble() throws Exception {
+// helpTest(LANG_FACTORY.createLiteral(new Long(1), Long.class), "double", "double(1)");
+// }
+//
+// public void testLongToBigDecimal() throws Exception {
+// helpTest(LANG_FACTORY.createLiteral(new Long(1), Long.class), "bigdecimal", "cast(1 AS numeric(31,12))");
+// }
+
+ // Source = BIGINTEGER
+
+ public void testBigIntegerToString() throws Exception {
+ helpTest(LANG_FACTORY.createLiteral(new BigInteger("1"), BigInteger.class), "string", "cast(1 AS varchar(4000))");
+ }
+
+ public void testBigIntegerToBoolean() throws Exception {
+ helpTest(LANG_FACTORY.createLiteral(new BigInteger("1"), BigInteger.class), "boolean", "CASE WHEN 1 = 0 THEN '0' WHEN 1 IS NOT NULL THEN '1' END");
+ }
+
+// public void testBigIntegerToByte() throws Exception {
+// helpTest(LANG_FACTORY.createLiteral(new BigInteger("1"), BigInteger.class), "byte", "smallint(1)");
+// }
+//
+// public void testBigIntegerToShort() throws Exception {
+// helpTest(LANG_FACTORY.createLiteral(new BigInteger("1"), BigInteger.class), "short", "smallint(1)");
+// }
+//
+// public void testBigIntegerToInteger() throws Exception {
+// helpTest(LANG_FACTORY.createLiteral(new BigInteger("1"), BigInteger.class), "integer", "integer(1)");
+// }
+//
+// public void testBigIntegerToLong() throws Exception {
+// helpTest(LANG_FACTORY.createLiteral(new BigInteger("1"), BigInteger.class), "long", "bigint(1)");
+// }
+//
+// public void testBigIntegerToFloat() throws Exception {
+// helpTest(LANG_FACTORY.createLiteral(new BigInteger("1"), BigInteger.class), "float", "cast(1 AS real)");
+// }
+//
+// public void testBigIntegerToDouble() throws Exception {
+// helpTest(LANG_FACTORY.createLiteral(new BigInteger("1"), BigInteger.class), "double", "double(1)");
+// }
+//
+// public void testBigIntegerToBigDecimal() throws Exception {
+// helpTest(LANG_FACTORY.createLiteral(new BigInteger("1"), BigInteger.class), "bigdecimal", "cast(1 AS numeric(31,12))");
+// }
+
+ // Source = FLOAT
+
+ public void testFloatToString() throws Exception {
+ helpTest(LANG_FACTORY.createLiteral(new Float(1.2f), Float.class), "string", "cast(1.2 AS varchar(4000))");
+ }
+
+ public void testFloatToBoolean() throws Exception {
+ helpTest(LANG_FACTORY.createLiteral(new Float(1.2f), Float.class), "boolean", "CASE WHEN 1.2 = 0 THEN '0' WHEN 1.2 IS NOT NULL THEN '1' END");
+ }
+
+// public void testFloatToByte() throws Exception {
+// helpTest(LANG_FACTORY.createLiteral(new Float(1.2f), Float.class), "byte", "smallint(1.2)");
+// }
+//
+// public void testFloatToShort() throws Exception {
+// helpTest(LANG_FACTORY.createLiteral(new Float(1.2f), Float.class), "short", "smallint(1.2)");
+// }
+//
+// public void testFloatToInteger() throws Exception {
+// helpTest(LANG_FACTORY.createLiteral(new Float(1.2f), Float.class), "integer", "integer(1.2)");
+// }
+//
+// public void testFloatToLong() throws Exception {
+// helpTest(LANG_FACTORY.createLiteral(new Float(1.2f), Float.class), "long", "bigint(1.2)");
+// }
+//
+// public void testFloatToBigInteger() throws Exception {
+// helpTest(LANG_FACTORY.createLiteral(new Float(1.2f), Float.class), "biginteger", "cast(1.2 AS numeric(31,0))");
+// }
+//
+// public void testFloatToDouble() throws Exception {
+// helpTest(LANG_FACTORY.createLiteral(new Float(1.2f), Float.class), "double", "double(1.2)");
+// }
+//
+// public void testFloatToBigDecimal() throws Exception {
+// helpTest(LANG_FACTORY.createLiteral(new Float(1.2f), Float.class), "bigdecimal", "cast(1.2 AS numeric(31,12))");
+// }
+
+ // Source = DOUBLE
+
+ public void testDoubleToString() throws Exception {
+ helpTest(LANG_FACTORY.createLiteral(new Double(1.2), Double.class), "string", "cast(1.2 AS varchar(4000))");
+ }
+
+ public void testDoubleToBoolean() throws Exception {
+ helpTest(LANG_FACTORY.createLiteral(new Double(1.2), Double.class), "boolean", "CASE WHEN 1.2 = 0 THEN '0' WHEN 1.2 IS NOT NULL THEN '1' END");
+ }
+
+// public void testDoubleToByte() throws Exception {
+// helpTest(LANG_FACTORY.createLiteral(new Double(1.2), Double.class), "byte", "smallint(1.2)");
+// }
+//
+// public void testDoubleToShort() throws Exception {
+// helpTest(LANG_FACTORY.createLiteral(new Double(1.2), Double.class), "short", "smallint(1.2)");
+// }
+//
+// public void testDoubleToInteger() throws Exception {
+// helpTest(LANG_FACTORY.createLiteral(new Double(1.2), Double.class), "integer", "integer(1.2)");
+// }
+//
+// public void testDoubleToLong() throws Exception {
+// helpTest(LANG_FACTORY.createLiteral(new Double(1.2), Double.class), "long", "bigint(1.2)");
+// }
+//
+// public void testDoubleToBigInteger() throws Exception {
+// helpTest(LANG_FACTORY.createLiteral(new Double(1.2), Double.class), "biginteger", "cast(1.2 AS numeric(31,0))");
+// }
+//
+// public void testDoubleToFloat() throws Exception {
+// helpTest(LANG_FACTORY.createLiteral(new Double(1.2), Double.class), "float", "cast(1.2 AS real)");
+// }
+//
+// public void testDoubleToBigDecimal() throws Exception {
+// helpTest(LANG_FACTORY.createLiteral(new Double(1.2), Double.class), "bigdecimal", "cast(1.2 AS numeric(31,12))");
+// }
+
+ // Source = BIGDECIMAL
+
+ public void testBigDecimalToString() throws Exception {
+ helpTest(LANG_FACTORY.createLiteral(new BigDecimal("1.0"), BigDecimal.class), "string", "cast(1.0 AS varchar(4000))");
+ }
+
+ public void testBigDecimalToBoolean() throws Exception {
+ helpTest(LANG_FACTORY.createLiteral(new BigDecimal("1.0"), BigDecimal.class), "boolean", "CASE WHEN 1.0 = 0 THEN '0' WHEN 1.0 IS NOT NULL THEN '1' END");
+ }
+
+// public void testBigDecimalToByte() throws Exception {
+// helpTest(LANG_FACTORY.createLiteral(new BigDecimal("1.0"), BigDecimal.class), "byte", "smallint(1.0)");
+// }
+//
+// public void testBigDecimalToShort() throws Exception {
+// helpTest(LANG_FACTORY.createLiteral(new BigDecimal("1.0"), BigDecimal.class), "short", "smallint(1.0)");
+// }
+//
+// public void testBigDecimalToInteger() throws Exception {
+// helpTest(LANG_FACTORY.createLiteral(new BigDecimal("1.0"), BigDecimal.class), "integer", "integer(1.0)");
+// }
+//
+// public void testBigDecimalToLong() throws Exception {
+// helpTest(LANG_FACTORY.createLiteral(new BigDecimal("1.0"), BigDecimal.class), "long", "bigint(1.0)");
+// }
+//
+// public void testBigDecimalToBigInteger() throws Exception {
+// helpTest(LANG_FACTORY.createLiteral(new BigDecimal("1.0"), BigDecimal.class), "biginteger", "cast(1.0 AS numeric(31,0))");
+// }
+//
+// public void testBigDecimalToFloat() throws Exception {
+// helpTest(LANG_FACTORY.createLiteral(new BigDecimal("1.0"), BigDecimal.class), "float", "cast(1.0 AS real)");
+// }
+//
+// public void testBigDecimalToDouble() throws Exception {
+// helpTest(LANG_FACTORY.createLiteral(new BigDecimal("1.0"), BigDecimal.class), "double", "double(1.0)");
+// }
+
+// // Source = DATE
+//
+// public void testDateToString() throws Exception {
+// helpTest(LANG_FACTORY.createLiteral(TimestampUtil.createDate(103, 10, 1), java.sql.Date.class), "string", "char({d '2003-11-01'})");
+// }
+//
+// public void testDateToTimestamp() throws Exception {
+// helpTest(LANG_FACTORY.createLiteral(TimestampUtil.createDate(103, 10, 1), java.sql.Date.class), "timestamp", "timestamp({d '2003-11-01'}, '00:00:00')");
+// }
+//
+// // Source = TIME
+//
+// public void testTimeToString() throws Exception {
+// helpTest(LANG_FACTORY.createLiteral(TimestampUtil.createTime(23, 59, 59), java.sql.Time.class), "string", "char({t '23:59:59'})");
+// }
+//
+// public void testTimeToTimestamp() throws Exception {
+// helpTest(LANG_FACTORY.createLiteral(TimestampUtil.createTime(23, 59, 59), java.sql.Time.class), "timestamp", "timestamp('1970-01-01', {t '23:59:59'})");
+// }
+//
+// // Source = TIMESTAMP
+//
+// public void testTimestampToString() throws Exception {
+// Timestamp ts = TimestampUtil.createTimestamp(103, 10, 1, 12, 5, 2, 0);
+// helpTest(LANG_FACTORY.createLiteral(ts, Timestamp.class), "string", "char({ts '2003-11-01 12:05:02.0'})");
+// }
+//
+// public void testTimestampToDate() throws Exception {
+// Timestamp ts = TimestampUtil.createTimestamp(103, 10, 1, 12, 5, 2, 0);
+// helpTest(LANG_FACTORY.createLiteral(ts, Timestamp.class), "date", "date({ts '2003-11-01 12:05:02.0'})");
+// }
+//
+// public void testTimestampToTime() throws Exception {
+// Timestamp ts = TimestampUtil.createTimestamp(103, 10, 1, 12, 5, 2, 0);
+// helpTest(LANG_FACTORY.createLiteral(ts, Timestamp.class), "time", "time({ts '2003-11-01 12:05:02.0'})");
+// }
+
+}
Property changes on: branches/7.4.x/connectors/translator-jdbc/src/test/java/org/teiid/translator/jdbc/netezza/TestNetezzaConvertModifier.java
___________________________________________________________________
Added: svn:mime-type
+ text/plain
Added: branches/7.4.x/connectors/translator-jdbc/src/test/java/org/teiid/translator/jdbc/netezza/TestNetezzaTranslatorCapabilities.java
===================================================================
--- branches/7.4.x/connectors/translator-jdbc/src/test/java/org/teiid/translator/jdbc/netezza/TestNetezzaTranslatorCapabilities.java (rev 0)
+++ branches/7.4.x/connectors/translator-jdbc/src/test/java/org/teiid/translator/jdbc/netezza/TestNetezzaTranslatorCapabilities.java 2011-08-04 12:09:55 UTC (rev 3358)
@@ -0,0 +1,394 @@
+/*
+ * 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.translator.jdbc.netezza;
+
+import junit.framework.TestCase;
+
+import org.junit.Test;
+import org.mockito.Mockito;
+import org.teiid.cdk.unittest.FakeTranslationFactory;
+import org.teiid.dqp.internal.datamgr.FakeExecutionContextImpl;
+import org.teiid.language.Command;
+import org.teiid.translator.ExecutionContext;
+import org.teiid.translator.TranslatorException;
+import org.teiid.translator.jdbc.TranslatedCommand;
+import org.teiid.translator.jdbc.TranslationHelper;
+
+public class TestNetezzaTranslatorCapabilities extends TestCase {
+
+ private static NetezzaExecutionFactory TRANSLATOR;
+ private static ExecutionContext EMPTY_CONTEXT = new FakeExecutionContextImpl();
+
+ static {
+ try {
+ TRANSLATOR = new NetezzaExecutionFactory();
+ TRANSLATOR.start();
+ } catch(TranslatorException e) {
+ e.printStackTrace();
+ }
+ }
+
+
+ private String getTestBQTVDB() {
+ return TranslationHelper.BQT_VDB;
+ }
+
+ public void helpTestVisitor(String input, String expectedOutput) throws TranslatorException {
+ // Convert from sql to objects
+ Command obj = FakeTranslationFactory.getInstance().getBQTTranslationUtility().parseCommand(input);
+
+ TranslatedCommand tc = new TranslatedCommand(Mockito.mock(ExecutionContext.class), TRANSLATOR);
+ tc.translateCommand(obj);
+
+
+ // Check stuff
+ assertEquals("Did not get correct sql", expectedOutput, tc.getSql());
+ }
+
+
+ /////////BASIC TEST CASES FOR CAPABILITIES/////////////
+ /////////////////////////////////////////////////
+ @Test
+ public void testRowLimit() throws Exception {
+ String input = "select intkey from bqt1.smalla limit 100";
+ String output = "SELECT SmallA.IntKey FROM SmallA LIMIT 100";
+
+ helpTestVisitor(
+ input,
+ output);
+
+ }
+ @Test
+ public void testSelectDistinct() throws Exception {
+ String input = "select distinct intkey from bqt1.smalla limit 100";
+ String output = "SELECT DISTINCT SmallA.IntKey FROM SmallA LIMIT 100";
+
+ helpTestVisitor(
+ input,
+ output);
+ }
+ @Test
+ public void testSelectExpression() throws Exception {
+ String input = "select intkey, intkey + longnum / 2 as test from bqt1.smalla";
+ String output = "SELECT SmallA.IntKey, (SmallA.IntKey + (SmallA.LongNum / 2)) AS test FROM SmallA";
+
+ helpTestVisitor(
+ input,
+ output);
+ }
+
+ public void testBetweenCriteria() throws Exception {
+ String input = "select intkey, intnum from bqt1.smalla where intnum BETWEEN 2 AND 10";
+ String output = "SELECT SmallA.IntKey, SmallA.IntNum FROM SmallA WHERE SmallA.IntNum >= 2 AND SmallA.IntNum <= 10";
+
+ helpTestVisitor(
+ input,
+ output);
+ }
+ public void testCompareCriteriaEquals() throws Exception {
+ String input = "select intkey, intnum from bqt1.smalla where intnum = 10";
+ String output = "SELECT SmallA.IntKey, SmallA.IntNum FROM SmallA WHERE SmallA.IntNum = 10";
+
+ helpTestVisitor(
+ input,
+ output);
+ }
+ public void testCompareCriteriaOrdered() throws Exception {
+ String input = "select intkey, intnum from bqt1.smalla where intnum < 10";
+ String output = "SELECT SmallA.IntKey, SmallA.IntNum FROM SmallA WHERE SmallA.IntNum < 10";
+
+ helpTestVisitor(
+ input,
+ output);
+ }
+ public void testLikeCriteria() throws Exception {
+ String input = "select intkey, intnum from bqt1.smalla where stringkey like '4%'";
+ String output = "SELECT SmallA.IntKey, SmallA.IntNum FROM SmallA WHERE SmallA.StringKey LIKE '4%'";
+
+ helpTestVisitor(
+ input,
+ output);
+ }
+ public void testLikeWithEscapeCriteria() throws Exception {
+ String input = "select intkey, intnum from bqt1.smalla where stringkey like '4\\%'";
+ String output = "SELECT SmallA.IntKey, SmallA.IntNum FROM SmallA WHERE SmallA.StringKey LIKE '4\\%'";
+
+ helpTestVisitor(
+ input,
+ output);
+ }
+
+ public void testInCriteria() throws Exception {
+ String input = "select intkey, intnum from bqt1.smalla where stringkey IN ('10', '11', '12')";
+ String output = "SELECT SmallA.IntKey, SmallA.IntNum FROM SmallA WHERE SmallA.StringKey IN ('10', '11', '12')";
+
+ helpTestVisitor(
+ input,
+ output);
+ }
+ public void testInCriteriaSubQuery() throws Exception {
+ String input = "select intkey, intnum from bqt1.smalla where stringkey IN (select stringkey from bqt1.smalla where intkey < 10)";
+ String output = "SELECT SmallA.IntKey, SmallA.IntNum FROM SmallA WHERE SmallA.StringKey IN (SELECT SmallA.StringKey FROM SmallA WHERE SmallA.IntKey < 10)";
+
+ helpTestVisitor(
+ input,
+ output);
+ }
+
+ public void testIsNullCriteria() throws Exception {
+ String input = "select intkey, intnum from bqt1.smalla where intnum IS NULL";
+ String output = "SELECT SmallA.IntKey, SmallA.IntNum FROM SmallA WHERE SmallA.IntNum IS NULL";
+
+ helpTestVisitor(
+ input,
+ output);
+ }
+ public void testOrCriteria() throws Exception {
+ String input = "select intkey, intnum from bqt1.smalla where intnum < 2 OR intnum > 10";
+ String output = "SELECT SmallA.IntKey, SmallA.IntNum FROM SmallA WHERE SmallA.IntNum < 2 OR SmallA.IntNum > 10";
+
+ helpTestVisitor(
+ input,
+ output);
+ }
+ @Test public void testIsNotNullCriteria() throws Exception {
+ String input = "select intkey, intnum from bqt1.smalla where intnum IS NOT NULL";
+ String output = "SELECT SmallA.IntKey, SmallA.IntNum FROM SmallA WHERE SmallA.IntNum IS NOT NULL";
+
+ helpTestVisitor(
+ input,
+ output);
+ }
+
+ @Test public void testExistsCriteria() throws Exception {
+ String input = "select intkey, intnum from bqt1.smalla where exists (select intkey from bqt1.smallb)";
+ String output = "SELECT SmallA.IntKey, SmallA.IntNum FROM SmallA WHERE EXISTS (SELECT SmallB.IntKey FROM SmallB LIMIT 1)";
+
+ helpTestVisitor(
+ input,
+ output);
+ }
+ @Test public void testHavingClauseCriteria() throws Exception {
+ String input = "SELECT INTKEY FROM BQT1.SMALLA GROUP BY INTKEY HAVING INTKEY = (SELECT INTKEY FROM BQT1.SMALLA WHERE STRINGKEY = 20)";
+ String output = "SELECT SmallA.IntKey FROM SmallA GROUP BY SmallA.IntKey HAVING SmallA.IntKey = (SELECT SmallA.IntKey FROM SmallA WHERE SmallA.StringKey = '20' LIMIT 2)";
+
+ helpTestVisitor(
+ input,
+ output);
+ }
+
+ @Test public void testScalarSubQuery() throws Exception {
+ String input = "select intkey, intnum from bqt1.smalla where intnum < (0.01 * (select sum(intnum) from bqt1.smalla ))";
+ String output = "SELECT SmallA.IntKey, SmallA.IntNum FROM SmallA WHERE SmallA.IntNum < (0.010000000000000 * (SELECT SUM(SmallA.IntNum) FROM SmallA))";
+
+ helpTestVisitor(
+ input,
+ output);
+ }
+
+ @Test public void testSimpleCaseExpression() throws Exception {
+ String input = "SELECT stringnum, intnum, CASE BOOLEANVALUE WHEN 'true' then 'true' WHEN false THEN 'FALSE' ELSE 'GOOD' END FROM bqt1.smalla;";
+ String output = "SELECT SmallA.StringNum, SmallA.IntNum, CASE WHEN SmallA.BooleanValue = 1 THEN 'true' WHEN SmallA.BooleanValue = 0 THEN 'FALSE' ELSE 'GOOD' END FROM SmallA";
+
+ helpTestVisitor(
+ input,
+ output);
+ }
+
+ @Test public void testSearchedCaseExpression() throws Exception {
+ String input = "SELECT AVG(CASE WHEN intnum > 10 THEN intnum ELSE intkey END) \"Average\" FROM bqt1.smalla";
+ String output = "SELECT AVG(CASE WHEN SmallA.IntNum > 10 THEN SmallA.IntNum ELSE SmallA.IntKey END) AS Average FROM SmallA";
+
+ helpTestVisitor(
+ input,
+ output);
+ }
+
+// @Test public void testQuantifiedCompareSOMEorANY() throws Exception {
+// String input = "SELECT INTKEY, BYTENUM FROM BQT1.SmallA WHERE BYTENUM = ANY (SELECT BYTENUM FROM BQT1.SmallA WHERE BYTENUM >= '-108')";
+// String output = "SELECT SmallA.IntKey, SmallA.ByteNum FROM SmallA WHERE SmallA.ByteNum = SOME (SELECT SmallA.ByteNum FROM SmallA WHERE SmallA.ByteNum >= -108)";
+//
+// helpTestVisitor(
+// input,
+// output);
+// }
+
+ @Test public void testQuantifiedCompareALL() throws Exception {
+ String input = "SELECT INTKEY, STRINGKEY FROM BQT1.SMALLA WHERE STRINGKEY = ALL (SELECT STRINGKEY FROM BQT1.SMALLA WHERE INTKEY = 40)";
+ String output = "SELECT SmallA.IntKey, SmallA.StringKey FROM SmallA WHERE SmallA.StringKey = ALL (SELECT SmallA.StringKey FROM SmallA WHERE SmallA.IntKey = 40)";
+
+ helpTestVisitor(
+ input,
+ output);
+ }
+
+ @Test public void testSelfJoin() throws Exception {
+ String input = "SELECT x.intnum, y.intkey FROM bqt1.smalla x, bqt1.smalla y WHERE x.stringnum = y.intnum;";
+ String output = "SELECT x.IntNum, y.IntKey FROM SmallA AS x, SmallA AS y WHERE x.StringNum = cast(y.IntNum AS varchar(4000))";
+
+ helpTestVisitor(
+ input,
+ output);
+ }
+
+ @Test public void testLimitWithNestedInlineView() throws Exception {
+ String input = "select max(intkey), stringkey from (select intkey, stringkey from bqt1.smalla order by intkey limit 100) x group by stringkey";
+ String output = "SELECT MAX(x.intkey), x.stringkey FROM (SELECT SmallA.IntKey, SmallA.StringKey FROM SmallA ORDER BY SmallA.IntKey LIMIT 100) AS x GROUP BY x.stringkey";
+
+ helpTestVisitor( input, output);
+ }
+
+ @Test public void testAggregatesAndEnhancedNumeric() throws Exception {
+ String input = "select count(*), min(intkey), max(intkey), sum(intkey), avg(intkey), count(intkey), STDDEV_SAMP(intkey), STDDEV_POP(intkey), VAR_SAMP(intkey), VAR_POP(intkey) from bqt1.smalla";
+ String output = "SELECT COUNT(*), MIN(SmallA.IntKey), MAX(SmallA.IntKey), SUM(SmallA.IntKey), AVG(SmallA.IntKey), COUNT(SmallA.IntKey), STDDEV_SAMP(SmallA.IntKey), STDDEV_POP(SmallA.IntKey), VAR_SAMP(SmallA.IntKey), VAR_POP(SmallA.IntKey) FROM SmallA";
+
+ helpTestVisitor( input, output);
+ }
+ @Test public void testAggregatesDistinct() throws Exception {
+ String input = "select avg(DISTINCT intnum) from bqt1.smalla";
+ String output = "SELECT AVG(DISTINCT SmallA.IntNum) FROM SmallA";
+
+ helpTestVisitor( input, output);
+ }
+
+
+ @Test public void testExceptAsMinus() throws Exception {
+ String input = "select intkey, intnum from bqt1.smalla except select intnum, intkey from bqt1.smallb";
+ String output = "SELECT SmallA.IntKey, SmallA.IntNum FROM SmallA EXCEPT SELECT SmallB.IntNum, SmallB.IntKey FROM SmallB";
+
+ helpTestVisitor( input, output);
+ }
+
+ @Test public void testUnionAsPlus() throws Exception {
+ String input = "select intkey, intnum from bqt1.smalla union select intnum, intkey from bqt1.smallb";
+ String output = "SELECT SmallA.IntKey, SmallA.IntNum FROM SmallA UNION SELECT SmallB.IntNum, SmallB.IntKey FROM SmallB";
+
+ helpTestVisitor( input, output);
+ }
+ @Test public void testUnionAllAsPlus() throws Exception {
+ String input = "select intkey, intnum from bqt1.smalla union all select intnum, intkey from bqt1.smallb";
+ String output = "SELECT SmallA.IntKey, SmallA.IntNum FROM SmallA UNION ALL SELECT SmallB.IntNum, SmallB.IntKey FROM SmallB";
+
+ helpTestVisitor( input, output);
+ }
+
+ @Test public void testUnionAllAsPlusWithAggregates() throws Exception {
+ String input = "select intkey, Sum(intnum) from bqt1.smalla group by intkey union all select intnum, intkey from bqt1.smallb";
+ String output = "SELECT SmallA.IntKey, SUM(SmallA.IntNum) FROM SmallA GROUP BY SmallA.IntKey UNION ALL SELECT SmallB.IntNum, SmallB.IntKey AS IntKey FROM SmallB";
+
+ helpTestVisitor( input, output);
+ }
+
+
+ @Test public void testintersect() throws Exception {
+ String input = "select intkey from bqt1.smalla where intkey < 20 INTERSECT select intkey from bqt1.smalla where intkey > 10";
+ String output = "SELECT SmallA.IntKey FROM SmallA WHERE SmallA.IntKey < 20 INTERSECT SELECT SmallA.IntKey FROM SmallA WHERE SmallA.IntKey > 10";
+
+
+ helpTestVisitor( input, output);
+ }
+
+
+ @Test public void testUnionOrderBy() throws Exception {
+ String input = "(select intkey from bqt1.smalla) union select intnum from bqt1.smalla order by intkey";
+ String output = "SELECT SmallA.IntKey FROM SmallA UNION SELECT SmallA.IntNum FROM SmallA ORDER BY intkey";
+
+ helpTestVisitor( input, output);
+
+ }
+
+ @Test public void testIntersectOrderBy() throws Exception {
+ String input = "(select intkey from bqt1.smalla) intersect select intnum from bqt1.smalla order by intkey";
+ String output = "SELECT SmallA.IntKey FROM SmallA INTERSECT SELECT SmallA.IntNum FROM SmallA ORDER BY intkey";
+
+ helpTestVisitor( input, output);
+
+ }
+
+ @Test public void testExceptOrderBy() throws Exception {
+ String input = "(select intkey from bqt1.smalla) except select intnum from bqt1.smalla order by intkey";
+ String output = "SELECT SmallA.IntKey FROM SmallA EXCEPT SELECT SmallA.IntNum FROM SmallA ORDER BY intkey";
+
+ helpTestVisitor( input, output);
+
+ }
+
+
+ @Test public void testRowLimitOFFSET() throws Exception {
+ String input = "select intkey from bqt1.smalla limit 20, 30";
+ String output = "SELECT SmallA.IntKey FROM SmallA LIMIT 30 OFFSET 20";
+
+ helpTestVisitor( input, output);
+ }
+
+
+ @Test public void testOrderByNullsFirstLast() throws Exception {
+ String input = "select intkey, longnum from bqt1.smalla order by longnum NULLS LAST";
+ String output = "SELECT SmallA.IntKey, SmallA.LongNum FROM SmallA ORDER BY SmallA.LongNum NULLS LAST";
+
+ helpTestVisitor( input, output);
+ }
+
+ @Test public void testOrderByUnRelated() throws Exception {
+ String input = "select intkey, longnum from bqt1.smalla order by floatnum";
+ String output = "SELECT SmallA.IntKey, SmallA.LongNum FROM SmallA ORDER BY SmallA.FloatNum";
+
+ helpTestVisitor( input, output);
+ }
+
+
+ @Test public void testInnerJoin() throws Exception {
+ String input = "SELECT BQT1.SmallA.IntKey FROM BQT1.SmallA, BQT2.SmallB WHERE BQT1.SmallA.IntKey = BQT2.SmallB.IntKey AND BQT1.SmallA.IntKey >= 0 AND BQT2.SmallB.IntKey >= 0 ORDER BY BQT1.SmallA.IntKey";
+ String output = "SELECT SmallA.IntKey FROM SmallA, SmallB WHERE SmallA.IntKey = SmallB.IntKey AND SmallA.IntKey >= 0 AND SmallB.IntKey >= 0 ORDER BY SmallA.IntKey";
+
+ helpTestVisitor( input, output);
+ }
+
+
+ @Test public void testOuterJoin() throws Exception {
+ String input = "SELECT BQT1.SmallA.IntKey FROM BQT1.SmallA, BQT2.SmallB WHERE BQT1.SmallA.IntKey = BQT2.SmallB.IntKey AND BQT1.SmallA.IntKey >= 0 AND BQT2.SmallB.IntKey >= 0 ORDER BY BQT1.SmallA.IntKey";
+ String output = "SELECT SmallA.IntKey FROM SmallA, SmallB WHERE SmallA.IntKey = SmallB.IntKey AND SmallA.IntKey >= 0 AND SmallB.IntKey >= 0 ORDER BY SmallA.IntKey";
+
+ helpTestVisitor( input, output);
+ }
+
+ @Test public void testFullOuterJoin() throws Exception {
+ String input = "SELECT BQT1.SmallA.IntNum, BQT2.SmallB.IntNum FROM BQT1.SmallA FULL OUTER JOIN BQT2.SmallB ON BQT1.SmallA.IntNum = BQT2.SmallB.IntNum ORDER BY BQT1.SmallA.IntNum";
+ String output = "SELECT SmallA.IntNum, SmallB.IntNum FROM SmallA FULL OUTER JOIN SmallB ON SmallA.IntNum = SmallB.IntNum ORDER BY SmallA.IntNum";
+
+ helpTestVisitor( input, output);
+ }
+
+ @Test public void testRightOuterJoin() throws Exception {
+ String input = "SELECT BQT1.SmallA.IntNum, BQT2.SmallB.IntNum FROM BQT1.SmallA RIGHT OUTER JOIN BQT2.SmallB ON BQT1.SmallA.IntNum = BQT2.SmallB.IntNum ORDER BY BQT2.SmallB.IntNum";
+ String output= "SELECT SmallA.IntNum, SmallB.IntNum FROM SmallB LEFT OUTER JOIN SmallA ON SmallA.IntNum = SmallB.IntNum ORDER BY SmallB.IntNum";
+
+ helpTestVisitor( input, output);
+ }
+ @Test public void testLeftOuterJoin() throws Exception {
+ String input = "SELECT BQT1.SmallA.IntNum, BQT2.SmallB.IntNum FROM BQT1.SmallA LEFT OUTER JOIN BQT2.SmallB ON BQT1.SmallA.IntNum = BQT2.SmallB.IntNum ORDER BY BQT1.SmallA.IntNum";
+ String output = "SELECT SmallA.IntNum, SmallB.IntNum FROM SmallA LEFT OUTER JOIN SmallB ON SmallA.IntNum = SmallB.IntNum ORDER BY SmallA.IntNum";
+
+ helpTestVisitor( input, output);
+ }
+
+}
Property changes on: branches/7.4.x/connectors/translator-jdbc/src/test/java/org/teiid/translator/jdbc/netezza/TestNetezzaTranslatorCapabilities.java
___________________________________________________________________
Added: svn:mime-type
+ text/plain
Added: branches/7.4.x/connectors/translator-jdbc/src/test/java/org/teiid/translator/jdbc/netezza/TestNetezzaTranslatorDatetimeConversion.java
===================================================================
--- branches/7.4.x/connectors/translator-jdbc/src/test/java/org/teiid/translator/jdbc/netezza/TestNetezzaTranslatorDatetimeConversion.java (rev 0)
+++ branches/7.4.x/connectors/translator-jdbc/src/test/java/org/teiid/translator/jdbc/netezza/TestNetezzaTranslatorDatetimeConversion.java 2011-08-04 12:09:55 UTC (rev 3358)
@@ -0,0 +1,141 @@
+/*
+ * 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.translator.jdbc.netezza;
+
+import static org.junit.Assert.assertEquals;
+
+import java.util.Arrays;
+
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.teiid.language.Expression;
+import org.teiid.language.Function;
+import org.teiid.language.LanguageFactory;
+import org.teiid.translator.TranslatorException;
+import org.teiid.translator.TypeFacility;
+import org.teiid.translator.jdbc.SQLConversionVisitor;
+import org.teiid.translator.jdbc.TranslationHelper;
+
+/**
+ */
+public class TestNetezzaTranslatorDatetimeConversion {
+
+ private static NetezzaExecutionFactory TRANSLATOR;
+ private static final LanguageFactory LANG_FACTORY = new LanguageFactory();
+
+ @BeforeClass public static void oneTimeSetup() throws TranslatorException {
+ TRANSLATOR = new NetezzaExecutionFactory();
+ TRANSLATOR.setUseBindVariables(false);
+ TRANSLATOR.start();
+
+
+ }
+
+ /////////////////UTILLITY FUNCTIONS/////////
+ ////////////////////////////////////////////
+
+ private String getTestVDB() {
+ //return TranslationHelper.NETEZZA_VDB;
+ return TranslationHelper.PARTS_VDB;
+ }
+
+ private String getTestBQTVDB() {
+ return TranslationHelper.BQT_VDB;
+ }
+
+ public void helpTest(Expression srcExpression, String tgtType, String expectedExpression) throws Exception {
+ Function func = LANG_FACTORY.createFunction("convert",
+ Arrays.asList( srcExpression,LANG_FACTORY.createLiteral(tgtType, String.class)),TypeFacility.getDataTypeClass(tgtType));
+
+ assertEquals("Error converting from " + srcExpression.getType() + " to " + tgtType,
+ expectedExpression, helpGetString(func));
+ }
+ public String helpGetString(Expression expr) throws Exception {
+ SQLConversionVisitor sqlVisitor = TRANSLATOR.getSQLConversionVisitor();
+ sqlVisitor.append(expr);
+
+ return sqlVisitor.toString();
+ }
+
+
+ ///////////////DATE/TIME CONVERSION TESTCASES///////
+ ////////////////////////////////////////////////////
+
+ @Test public void testdayofmonth() throws Exception {
+ String input = "SELECT dayofmonth(datevalue) FROM BQT1.SMALLA";
+ String output = "SELECT extract(DAY from SmallA.DateValue) FROM SmallA";
+
+ TranslationHelper.helpTestVisitor(getTestBQTVDB(), input, output, TRANSLATOR);
+ }
+
+
+ ///BEGIN--FROM TIMESTAMP->DATE, TIME, STRING////////
+ @Test public void testTimestampToDate() throws Exception {
+ String input = "SELECT convert(convert(TIMESTAMPVALUE, date), string) FROM BQT1.SMALLA";
+ String output = "SELECT cast(cast(SmallA.TimestampValue AS DATE) AS varchar(4000)) FROM SmallA";
+
+ TranslationHelper.helpTestVisitor(getTestBQTVDB(), input, output, TRANSLATOR);
+ }
+ @Test public void testTimestampToTime() throws Exception {
+ String input = "SELECT convert(convert(TIMESTAMPVALUE, time), string) FROM BQT1.SMALLA";
+ String output = "SELECT cast(cast(SmallA.TimestampValue AS TIME) AS varchar(4000)) FROM SmallA";
+
+ TranslationHelper.helpTestVisitor(getTestBQTVDB(), input, output, TRANSLATOR);
+ }
+
+ @Test public void testTimestampToString() throws Exception {
+ String input = "SELECT convert(timestampvalue, string) FROM BQT1.SMALLA";
+ String output = "SELECT to_char(SmallA.TimestampValue, 'YYYY-MM-DD HH24:MI:SS.MS') FROM SmallA";
+
+ TranslationHelper.helpTestVisitor(getTestBQTVDB(), input, output, TRANSLATOR);
+ }
+ ///END--FROM TIMESTAMP->DATE, TIME, STRING////////
+
+ ///BEGIN--FROM DATE->TIMESTAMP////////
+ @Test public void testDateToTimestamp() throws Exception {
+ String input = "SELECT convert(convert(datevalue, timestamp), string) FROM BQT1.SMALLA";
+ String output = "SELECT to_char(cast(SmallA.DateValue AS TIMESTAMP), 'YYYY-MM-DD HH24:MI:SS.MS') FROM SmallA";
+
+ TranslationHelper.helpTestVisitor(getTestBQTVDB(), input, output, TRANSLATOR);
+ }
+ ///END--FROM DATE->TIMESTAMP////////
+
+ ///BEGIN--FROM TIME->TIMESTAMP////////
+ @Test public void testTimeToTimestamp() throws Exception {
+ String input = "SELECT convert(convert(TIMEVALUE, timestamp), string) FROM BQT1.SMALLA";
+ //String output = "SELECT to_char(cast(SmallA.TimeValue AS timestamp), 'YYYY-MM-DD HH24:MI:SS.FF') FROM SmallA";
+ String output = "SELECT to_char(SmallA.TimeValue, 'YYYY-MM-DD HH24:MI:SS.MS') FROM SmallA";
+
+ TranslationHelper.helpTestVisitor(getTestBQTVDB(), input, output, TRANSLATOR);
+ }
+ ///END--FROM TIME->TIMESTAMP////////
+
+
+// @Test public void testTimestampToTime() throws Exception {
+// helpTest(LANG_FACTORY.createLiteral(TimestampUtil.createTimestamp(111, 4, 5, 9, 16, 34, 220000000), Timestamp.class), "TIME", "cast(cast('2011-05-05 09:16:34.22' AS TIMESTAMP(6)) AS TIME)");
+// }
+
+
+
+
+}
Property changes on: branches/7.4.x/connectors/translator-jdbc/src/test/java/org/teiid/translator/jdbc/netezza/TestNetezzaTranslatorDatetimeConversion.java
___________________________________________________________________
Added: svn:mime-type
+ text/plain
Added: branches/7.4.x/connectors/translator-jdbc/src/test/java/org/teiid/translator/jdbc/netezza/TestNetezzaTranslatorSourceSystemFunctions.java
===================================================================
--- branches/7.4.x/connectors/translator-jdbc/src/test/java/org/teiid/translator/jdbc/netezza/TestNetezzaTranslatorSourceSystemFunctions.java (rev 0)
+++ branches/7.4.x/connectors/translator-jdbc/src/test/java/org/teiid/translator/jdbc/netezza/TestNetezzaTranslatorSourceSystemFunctions.java 2011-08-04 12:09:55 UTC (rev 3358)
@@ -0,0 +1,243 @@
+/*
+ * 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.translator.jdbc.netezza;
+
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.teiid.language.LanguageFactory;
+import org.teiid.translator.TranslatorException;
+import org.teiid.translator.jdbc.TranslationHelper;
+
+/**
+ */
+public class TestNetezzaTranslatorSourceSystemFunctions {
+
+ private static NetezzaExecutionFactory TRANSLATOR;
+ private static final LanguageFactory LANG_FACTORY = new LanguageFactory();
+
+ @BeforeClass public static void oneTimeSetup() throws TranslatorException {
+ TRANSLATOR = new NetezzaExecutionFactory();
+ TRANSLATOR.setUseBindVariables(false);
+ TRANSLATOR.start();
+
+
+ }
+
+
+ /////////////////UTILLITY FUNCTIONS/////////
+ ////////////////////////////////////////////
+
+
+ private String getTestBQTVDB() {
+ return TranslationHelper.BQT_VDB;
+ }
+
+
+ /////SOURCESYSTEM FUNCTION TESTCASES//////////////
+ ///////////////////////////////////////////////
+
+
+ //////////////////BEGIN---STRING FUNCTIONS TESTCASES///////////////////
+
+ @Test
+ public void testLcaseUcase() throws Exception {
+ String input = "select lcase(StringKey), ucase(StringKey) FROM BQT1.SmallA";
+ String output = "SELECT lower(SmallA.StringKey), upper(SmallA.StringKey) FROM SmallA";
+
+ TranslationHelper.helpTestVisitor(getTestBQTVDB(), input, output,TRANSLATOR);
+ }
+ @Test public void testPad() throws Exception {
+ String input = "select lpad(smalla.stringkey, 18), rpad(smalla.stringkey, 12) from bqt1.smalla"; //$NON-NLS-1$
+ String output = "SELECT lpad(SmallA.StringKey, 18), rpad(SmallA.StringKey, 12) FROM SmallA"; //$NON-NLS-1$
+
+ TranslationHelper.helpTestVisitor(TranslationHelper.BQT_VDB,
+ input,
+ output, TRANSLATOR);
+ }
+
+ @Test
+ public void testIFNull() throws Exception {
+ String input = "SELECT ifnull(StringKey, 'otherString') FROM BQT1.SmallA";
+ String output = "SELECT NVL(SmallA.StringKey, 'otherString') FROM SmallA";
+ //SELECT IFNULL(GL_ACTG_APPL_ID, 'otherString') FROM ACTG_UNIT_BAL_FACT
+ //SELECT nvl(GL_ACTG_APPL_ID, 'otherString') FROM ACTG_UNIT_BAL_FACT
+
+ TranslationHelper.helpTestVisitor(getTestBQTVDB(), input, output, TRANSLATOR);
+ }
+
+
+ @Test public void testSubstring1() throws Exception {
+
+ //////////BOTH SUBSTRING AND SUBSTR work in NETEZZA//
+ //////////////////////////////////////////////////////
+ String input = "SELECT substring(StringKey, 1) FROM BQT1.SmallA";
+ String output = "SELECT substring(SmallA.StringKey, 1) FROM SmallA";
+ //SELECT substring(FDL_PMF_ACCT, 3) FROM ACTG_UNIT_BAL_FACT
+ //SELECT substr(FDL_PMF_ACCT, 3) FROM ACTG_UNIT_BAL_FACT
+ TranslationHelper.helpTestVisitor(getTestBQTVDB(), input, output, TRANSLATOR);
+ }
+ @Test public void testSubstring2() throws Exception {
+
+ //////////BOTH SUBSTRING AND SUBSTR work in NETEZZA//
+ //////////////////////////////////////////////////////
+ String input = "SELECT substring(StringKey, 1, 5) FROM BQT1.SmallA";
+ String output = "SELECT substring(SmallA.StringKey, 1, 5) FROM SmallA";
+ TranslationHelper.helpTestVisitor(getTestBQTVDB(), input, output, TRANSLATOR);
+ }
+
+
+
+ @Test public void testConcat_withLiteral() throws Exception {
+// String sql = "select stringnum || '1' from BQT1.Smalla";
+// String expected = "SELECT CASE WHEN SmallA.StringNum IS NULL THEN NULL ELSE concat(SmallA.StringNum, '1') END FROM SmallA";
+// helpTestVisitor(FakeMetadataFactory.exampleBQTCached(), sql, EMPTY_CONTEXT, null, expected);
+ String input = "select stringnum || '1' from BQT1.Smalla";
+ String output = "SELECT (SmallA.StringNum || '1') FROM SmallA";
+
+ TranslationHelper.helpTestVisitor(getTestBQTVDB(), input, output, TRANSLATOR);
+ }
+
+
+
+ ////BEGIN-LOCATE FUNCTION
+ @Test public void testLocate() throws Exception {
+ String input = "SELECT locate(INTNUM, 'chimp', 1) FROM BQT1.SMALLA";
+ String output = "SELECT INSTR('chimp', cast(SmallA.IntNum AS varchar(4000)), 1) FROM SmallA";
+
+ TranslationHelper.helpTestVisitor(TranslationHelper.BQT_VDB,
+ input, output,
+ TRANSLATOR);
+ }
+
+ @Test public void testLocate2() throws Exception {
+ String input = "SELECT locate(STRINGNUM, 'chimp') FROM BQT1.SMALLA";
+ String output = "SELECT INSTR('chimp', SmallA.StringNum) FROM SmallA";
+
+ TranslationHelper.helpTestVisitor(TranslationHelper.BQT_VDB,
+ input, output,
+ TRANSLATOR);
+ }
+
+ @Test public void testLocate3() throws Exception {
+ String input = "SELECT locate(INTNUM, '234567890', 1) FROM BQT1.SMALLA WHERE INTKEY = 26";
+ String output = "SELECT INSTR('234567890', cast(SmallA.IntNum AS varchar(4000)), 1) FROM SmallA WHERE SmallA.IntKey = 26";
+
+ TranslationHelper.helpTestVisitor(TranslationHelper.BQT_VDB, input, output, TRANSLATOR);
+ }
+
+ @Test public void testLocate4() throws Exception {
+ String input = "SELECT locate('c', 'chimp', 1) FROM BQT1.SMALLA";
+ String output = "SELECT 1 FROM SmallA";
+
+ TranslationHelper.helpTestVisitor(TranslationHelper.BQT_VDB, input, output, TRANSLATOR);
+ }
+
+ @Test public void testLocate5() throws Exception {
+ String input = "SELECT locate(STRINGNUM, 'chimp', -5) FROM BQT1.SMALLA";
+ String output = "SELECT INSTR('chimp', SmallA.StringNum, 1) FROM SmallA";
+
+ TranslationHelper.helpTestVisitor(TranslationHelper.BQT_VDB, input, output, TRANSLATOR);
+ }
+
+ @Test public void testLocate6() throws Exception {
+ String input = "SELECT locate(STRINGNUM, 'chimp', INTNUM) FROM BQT1.SMALLA";
+ String output = "SELECT INSTR('chimp', SmallA.StringNum, CASE WHEN SmallA.IntNum < 1 THEN 1 ELSE SmallA.IntNum END) FROM SmallA";
+
+ TranslationHelper.helpTestVisitor(TranslationHelper.BQT_VDB, input, output, TRANSLATOR);
+ }
+
+ @Test public void testLocate7() throws Exception {
+ String input = "SELECT locate(STRINGNUM, 'chimp', LOCATE(STRINGNUM, 'chimp') + 1) FROM BQT1.SMALLA";
+ String output = "SELECT INSTR('chimp', SmallA.StringNum, CASE WHEN (INSTR('chimp', SmallA.StringNum) + 1) < 1 THEN 1 ELSE (INSTR('chimp', SmallA.StringNum) + 1) END) FROM SmallA";
+
+ TranslationHelper.helpTestVisitor(TranslationHelper.BQT_VDB, input, output, TRANSLATOR);
+ }
+ ////END-LOCATE FUNCTION
+
+
+
+
+ //////////////////BEGIN---NUMERIC FUNCTIONS TESTCASES///////////////////
+ @Test public void testCeil() throws Exception {
+ //select ceiling(sqrt(MEAS_PRD_ID)) from ACTG_UNIT_BAL_FACT
+ //select ceil(sqrt(MEAS_PRD_ID)) from ACTG_UNIT_BAL_FACT
+ String input = "SELECT ceiling(sqrt(INTKEY)) FROM BQT1.SMALLA";
+ String output = "SELECT ceil(sqrt(SmallA.IntKey)) FROM SmallA";
+ TranslationHelper.helpTestVisitor(getTestBQTVDB(),
+ input,
+ output, TRANSLATOR);
+ }
+
+ @Test public void testPower() throws Exception {
+
+ //select power(MEAS_PRD_ID, 2) from ACTG_UNIT_BAL_FACT
+ //select pow(MEAS_PRD_ID, 2) from ACTG_UNIT_BAL_FACT
+ String input = "SELECT power(INTKEY, 2) FROM BQT1.SMALLA";
+ String output = "SELECT pow(SmallA.IntKey, 2) FROM SmallA";
+ TranslationHelper.helpTestVisitor(getTestBQTVDB(),
+ input,
+ output, TRANSLATOR);
+ }
+ //////////////////END---NUMERIC FUNCTIONS TESTCASES///////////////////
+
+
+ //////////////////BEGIN---BIT FUNCTIONS CONVERSION TESTCASES///////////////////
+ ///////////////////////////////////////////////////////////////////
+
+ @Test public void testBitAnd() throws Exception {
+ String input = "select bitand(intkey, intnum) from bqt1.smalla";
+ String output = "SELECT intNand(SmallA.IntKey, SmallA.IntNum) FROM SmallA";
+
+ TranslationHelper.helpTestVisitor(TranslationHelper.BQT_VDB,
+ input,
+ output, TRANSLATOR);
+ }
+ @Test public void testBitNot() throws Exception {
+ String input = "select bitnot(intkey) from bqt1.smalla";
+ String output = "SELECT intNnot(SmallA.IntKey) FROM SmallA";
+
+ TranslationHelper.helpTestVisitor(TranslationHelper.BQT_VDB,
+ input,
+ output, TRANSLATOR);
+ }
+ @Test public void testBitOr() throws Exception {
+ String input = "select bitor(intkey, intnum) from bqt1.smalla";
+ String output = "SELECT intNor(SmallA.IntKey, SmallA.IntNum) FROM SmallA";
+
+ TranslationHelper.helpTestVisitor(TranslationHelper.BQT_VDB,
+ input,
+ output, TRANSLATOR);
+ }
+ @Test public void testBitXor() throws Exception {
+ String input = "select bitxor(intkey, intnum) from bqt1.smalla";
+ String output = "SELECT intNxor(SmallA.IntKey, SmallA.IntNum) FROM SmallA";
+
+ TranslationHelper.helpTestVisitor(TranslationHelper.BQT_VDB,
+ input,
+ output, TRANSLATOR);
+ }
+ //////////////////END---BIT FUNCTIONS CONVERSION TESTCASES///////////////////
+ /////////////////////////////////////////////////////////////////////////////
+
+
+}
Property changes on: branches/7.4.x/connectors/translator-jdbc/src/test/java/org/teiid/translator/jdbc/netezza/TestNetezzaTranslatorSourceSystemFunctions.java
___________________________________________________________________
Added: svn:mime-type
+ text/plain
Added: branches/7.4.x/connectors/translator-jdbc/src/test/java/org/teiid/translator/jdbc/netezza/TestNetezzaTranslatorTypeMapping.java
===================================================================
--- branches/7.4.x/connectors/translator-jdbc/src/test/java/org/teiid/translator/jdbc/netezza/TestNetezzaTranslatorTypeMapping.java (rev 0)
+++ branches/7.4.x/connectors/translator-jdbc/src/test/java/org/teiid/translator/jdbc/netezza/TestNetezzaTranslatorTypeMapping.java 2011-08-04 12:09:55 UTC (rev 3358)
@@ -0,0 +1,246 @@
+/*
+ * 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.translator.jdbc.netezza;
+
+import static org.junit.Assert.assertEquals;
+
+import java.util.Arrays;
+
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.teiid.language.Expression;
+import org.teiid.language.Function;
+import org.teiid.language.LanguageFactory;
+import org.teiid.translator.TranslatorException;
+import org.teiid.translator.TypeFacility;
+import org.teiid.translator.jdbc.SQLConversionVisitor;
+import org.teiid.translator.jdbc.TranslationHelper;
+
+
+public class TestNetezzaTranslatorTypeMapping {
+
+ private static NetezzaExecutionFactory TRANSLATOR;
+ private static final LanguageFactory LANG_FACTORY = new LanguageFactory();
+
+ @BeforeClass public static void oneTimeSetup() throws TranslatorException {
+ TRANSLATOR = new NetezzaExecutionFactory();
+ TRANSLATOR.setUseBindVariables(false);
+ TRANSLATOR.start();
+
+
+ }
+
+
+ /////////////////UTILLITY FUNCTIONS/////////
+ ////////////////////////////////////////////
+
+ private String getTestBQTVDB() {
+
+ return TranslationHelper.BQT_VDB;
+ }
+
+
+ public void helpTest(Expression srcExpression, String tgtType, String expectedExpression) throws Exception {
+ Function func = LANG_FACTORY.createFunction("convert",
+ Arrays.asList( srcExpression,LANG_FACTORY.createLiteral(tgtType, String.class)),TypeFacility.getDataTypeClass(tgtType));
+
+ assertEquals("Error converting from " + srcExpression.getType() + " to " + tgtType,
+ expectedExpression, helpGetString(func));
+ }
+ public String helpGetString(Expression expr) throws Exception {
+ SQLConversionVisitor sqlVisitor = TRANSLATOR.getSQLConversionVisitor();
+ sqlVisitor.append(expr);
+
+ return sqlVisitor.toString();
+ }
+
+
+ /////////TYPE MAPPING TESTS/////////
+ ///////////////////////////////////
+
+ @Test public void testCHARtoChar1() throws Exception {
+ String input = "SELECT convert(StringKey, CHAR) FROM BQT1.SmallA";
+ String output = "SELECT cast(SmallA.StringKey AS char(1)) FROM SmallA";
+
+ TranslationHelper.helpTestVisitor(getTestBQTVDB(),
+ input,
+ output, TRANSLATOR);
+ }
+
+ @Test public void testLongToBigInt() throws Exception {
+ String input = "SELECT convert(convert(StringKey, long), string) FROM BQT1.SmallA";
+ String output = "SELECT cast(cast(SmallA.StringKey AS bigint) AS varchar(4000)) FROM SmallA";
+
+ TranslationHelper.helpTestVisitor(getTestBQTVDB(),
+ input,
+ output, TRANSLATOR);
+ }
+ @Test public void testStringToByte() throws Exception {
+ String input = "SELECT char(convert(stringnum, byte) + 100) FROM BQT1.SMALLA";
+ String output = "SELECT chr((cast(SmallA.StringNum AS byteint) + 100)) FROM SmallA";
+
+ TranslationHelper.helpTestVisitor(getTestBQTVDB(),
+ input,
+ output, TRANSLATOR);
+ }
+ @Test public void testStringToShort() throws Exception {
+ String input = "SELECT char(convert(stringnum, short) + 100) FROM BQT1.SMALLA";
+ String output = "SELECT chr((cast(SmallA.StringNum AS smallint) + 100)) FROM SmallA";
+
+ TranslationHelper.helpTestVisitor(getTestBQTVDB(),
+ input,
+ output, TRANSLATOR);
+ }
+ @Test public void testStringToLong() throws Exception {
+// String input = "SELECT char(convert(PART_WEIGHT, long) + 100) FROM PARTS";
+// String output = "SELECT chr((cast(PARTS.PART_WEIGHT AS bigint) + 100)) FROM PARTS";
+ String input = "SELECT convert(stringnum, long) FROM BQT1.SMALLA";
+ String output = "SELECT cast(SmallA.StringNum AS bigint) FROM SmallA";
+
+ TranslationHelper.helpTestVisitor(getTestBQTVDB(),
+ input,
+ output, TRANSLATOR);
+ }
+ @Test public void testStringToBiginteger() throws Exception {
+ String input = "SELECT convert(stringnum, BIGINTEGER) FROM BQT1.SMALLA";
+ String output = "SELECT cast(SmallA.StringNum AS numeric(38)) FROM SmallA";
+
+ TranslationHelper.helpTestVisitor(getTestBQTVDB(),
+ input,
+ output, TRANSLATOR);
+ }
+
+ @Test public void testStringToBigdecimal() throws Exception {
+ String input = "SELECT convert(stringnum, BIGDECIMAL) FROM BQT1.SMALLA";
+ String output = "SELECT cast(SmallA.StringNum AS numeric(38,18)) FROM SmallA";
+
+ TranslationHelper.helpTestVisitor(getTestBQTVDB(),
+ input,
+ output, TRANSLATOR);
+ }
+
+ @Test public void testStringToVarchar() throws Exception {
+ String input = "SELECT convert(intkey, STRING) FROM BQT1.SMALLA";
+ String output = "SELECT cast(SmallA.IntKey AS varchar(4000)) FROM SmallA";
+
+ TranslationHelper.helpTestVisitor(getTestBQTVDB(),
+ input,
+ output, TRANSLATOR);
+ }
+
+
+
+
+ ////NON-MAPPED TYPES TEST/////////////
+ //////////////////////////////////////
+
+ @Test public void testStringToInteger() throws Exception {
+ String input = "SELECT char(convert(stringnum, integer) + 100) FROM BQT1.SMALLA";
+ String output = "SELECT chr((cast(SmallA.StringNum AS integer) + 100)) FROM SmallA";
+
+ TranslationHelper.helpTestVisitor(getTestBQTVDB(),
+ input,
+ output, TRANSLATOR);
+ }
+
+ @Test public void testStringToFloat() throws Exception {
+ String input = "SELECT convert(stringnum, float) FROM BQT1.SMALLA";
+ String output = "SELECT cast(SmallA.StringNum AS float) FROM SmallA";
+
+ TranslationHelper.helpTestVisitor(getTestBQTVDB(),
+ input,
+ output, TRANSLATOR);
+ }
+ @Test public void testStringToReal() throws Exception {
+ String input = "SELECT convert(stringnum, real) FROM BQT1.SMALLA";
+ String output = "SELECT cast(SmallA.StringNum AS float) FROM SmallA";
+
+ TranslationHelper.helpTestVisitor(getTestBQTVDB(),
+ input,
+ output, TRANSLATOR);
+ }
+ @Test public void testStringToDouble() throws Exception {
+ String input = "SELECT convert(stringnum, double) FROM BQT1.SMALLA";
+ String output = "SELECT cast(SmallA.StringNum AS double) FROM SmallA";
+ //SELECT cast(MEAS_PRD_ID AS DOUBLE) from ACTG_UNIT_BAL_FACT
+
+ TranslationHelper.helpTestVisitor(getTestBQTVDB(),
+ input,
+ output, TRANSLATOR);
+ }
+ @Test public void testStringToBoolean() throws Exception {
+ String input = "SELECT convert(stringnum, boolean) FROM BQT1.SMALLA";
+ String output = "SELECT CASE WHEN SmallA.StringNum IN ('false', '0') THEN '0' WHEN SmallA.StringNum IS NOT NULL THEN '1' END FROM SmallA";
+
+ TranslationHelper.helpTestVisitor(getTestBQTVDB(),
+ input,
+ output, TRANSLATOR);
+ }
+ @Test public void testStringToDate() throws Exception {
+ String input = "SELECT convert(stringnum, date) FROM BQT1.SMALLA";
+ String output = "SELECT to_date(SmallA.StringNum, 'YYYY-MM-DD') FROM SmallA";
+
+ TranslationHelper.helpTestVisitor(getTestBQTVDB(),
+ input,
+ output, TRANSLATOR);
+ }
+ @Test public void testStringToTime() throws Exception {
+ String input = "SELECT convert(stringnum, time) FROM BQT1.SMALLA";
+ String output = "SELECT to_timestamp(SmallA.StringNum, 'HH24:MI:SS') FROM SmallA";
+
+ TranslationHelper.helpTestVisitor(getTestBQTVDB(),
+ input,
+ output, TRANSLATOR);
+ }
+ @Test public void testStringToTimestamp() throws Exception {
+ String input = "SELECT convert(stringnum, timestamp) FROM BQT1.SMALLA";
+ String output = "SELECT to_timestamp(SmallA.StringNum, 'YYYY-MM-DD HH24:MI:SS.MS') FROM SmallA";
+
+ TranslationHelper.helpTestVisitor(getTestBQTVDB(),
+ input,
+ output, TRANSLATOR);
+ }
+
+
+ @Test public void testbooleanToIntegerConversion() throws Exception {
+ String input = "SELECT BQT1.SmallA.IntNum, BQT2.SmallB.BooleanValue FROM BQT1.SmallA, BQT2.SmallB WHERE BQT1.SmallA.IntNum = convert(BQT2.SmallB.booleanvalue, integer)";
+ String output = "SELECT SmallA.IntNum, SmallB.BooleanValue FROM SmallA, SmallB WHERE SmallA.IntNum = (CASE WHEN SmallB.BooleanValue IN ( '0', 'FALSE') THEN 0 WHEN SmallB.BooleanValue IS NOT NULL THEN 1 END)";
+ TranslationHelper.helpTestVisitor(getTestBQTVDB(),
+ input,
+ output, TRANSLATOR);
+
+
+ }
+
+ @Test public void testIntegerToBooleanconversion() throws Exception {
+ String input = "SELECT BQT1.SmallA.IntNum, BQT2.SmallB.BooleanValue FROM BQT1.SmallA, BQT2.SmallB WHERE BQT1.SmallA.booleanvalue = convert(BQT2.SmallB.IntNum, boolean) AND BQT1.SmallA.IntKey >= 0 AND BQT2.SmallB.IntKey >= 0 ORDER BY BQT1.SmallA.IntNum";
+ String output = "SELECT SmallA.IntNum, SmallB.BooleanValue FROM SmallA, SmallB WHERE SmallA.BooleanValue = CASE WHEN SmallB.IntNum = 0 THEN '0' WHEN SmallB.IntNum IS NOT NULL THEN '1' END AND SmallA.IntKey >= 0 AND SmallB.IntKey >= 0 ORDER BY SmallA.IntNum";
+ TranslationHelper.helpTestVisitor(getTestBQTVDB(),
+ input,
+ output, TRANSLATOR);
+
+
+ }
+
+
+}
Property changes on: branches/7.4.x/connectors/translator-jdbc/src/test/java/org/teiid/translator/jdbc/netezza/TestNetezzaTranslatorTypeMapping.java
___________________________________________________________________
Added: svn:mime-type
+ text/plain
Added: branches/7.4.x/connectors/translator-jdbc/src/test/java/org/teiid/translator/jdbc/netezza/TestSubstringFunctionModifier.java
===================================================================
--- branches/7.4.x/connectors/translator-jdbc/src/test/java/org/teiid/translator/jdbc/netezza/TestSubstringFunctionModifier.java (rev 0)
+++ branches/7.4.x/connectors/translator-jdbc/src/test/java/org/teiid/translator/jdbc/netezza/TestSubstringFunctionModifier.java 2011-08-04 12:09:55 UTC (rev 3358)
@@ -0,0 +1,98 @@
+/*
+ * 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.translator.jdbc.netezza;
+
+import java.util.Arrays;
+
+import junit.framework.TestCase;
+
+import org.teiid.language.Expression;
+import org.teiid.language.Function;
+import org.teiid.language.LanguageFactory;
+import org.teiid.translator.TypeFacility;
+import org.teiid.translator.jdbc.SQLConversionVisitor;
+
+/**
+ */
+public class TestSubstringFunctionModifier extends TestCase {
+
+ private static final LanguageFactory LANG_FACTORY = new LanguageFactory();
+
+
+ /**
+ * Constructor for TestSubstringFunctionModifier.
+ * @param name
+ */
+ public TestSubstringFunctionModifier(String name) {
+ super(name);
+ }
+
+ public void helpTestMod(Expression[] args, String expectedStr) throws Exception {
+ Function func = LANG_FACTORY.createFunction("substring",
+ Arrays.asList(args), TypeFacility.RUNTIME_TYPES.STRING);
+
+ NetezzaExecutionFactory trans = new NetezzaExecutionFactory();
+ trans.start();
+
+ SQLConversionVisitor sqlVisitor = trans.getSQLConversionVisitor();
+ sqlVisitor.append(func);
+
+ assertEquals(expectedStr, sqlVisitor.toString());
+ }
+
+ public void testTwoArgs() throws Exception {
+ Expression[] args = new Expression[] {
+ LANG_FACTORY.createLiteral("a.b.c", String.class),
+ LANG_FACTORY.createLiteral(new Integer(1), Integer.class)
+ };
+ helpTestMod(args, "substring('a.b.c', 1)");
+ }
+
+ public void testThreeArgsWithConstant() throws Exception {
+ Expression[] args = new Expression[] {
+ LANG_FACTORY.createLiteral("a.b.c", String.class),
+ LANG_FACTORY.createLiteral(new Integer(3), Integer.class),
+ LANG_FACTORY.createLiteral(new Integer(1), Integer.class)
+ };
+ helpTestMod(args, "substring('a.b.c', 3, 1)");
+ }
+
+ public void testThreeArgsWithElement() throws Exception {
+ Expression[] args = new Expression[] {
+ LANG_FACTORY.createLiteral("a.b.c", String.class),
+ LANG_FACTORY.createColumnReference("e1", null, null, Integer.class),
+ LANG_FACTORY.createLiteral(new Integer(1), Integer.class)
+ };
+ helpTestMod(args, "substring('a.b.c', e1, 1)");
+ }
+
+ public void testThreeArgsWithNull() throws Exception {
+ Expression[] args = new Expression[] {
+ LANG_FACTORY.createLiteral("a.b.c", String.class),
+ LANG_FACTORY.createLiteral(null, Integer.class),
+ LANG_FACTORY.createLiteral(new Integer(5), Integer.class)
+ };
+ helpTestMod(args, "substring('a.b.c', NULL, 5)");
+ }
+
+}
Property changes on: branches/7.4.x/connectors/translator-jdbc/src/test/java/org/teiid/translator/jdbc/netezza/TestSubstringFunctionModifier.java
___________________________________________________________________
Added: svn:mime-type
+ text/plain
14 years, 8 months
teiid SVN: r3357 - in branches/7.4.x: connectors/translator-ldap/src/main/java/org/teiid/translator/ldap and 1 other directories.
by teiid-commits@lists.jboss.org
Author: shawkins
Date: 2011-08-03 11:13:06 -0400 (Wed, 03 Aug 2011)
New Revision: 3357
Modified:
branches/7.4.x/build/kits/jboss-container/teiid-releasenotes.html
branches/7.4.x/connectors/translator-ldap/src/main/java/org/teiid/translator/ldap/LDAPExecutionFactory.java
branches/7.4.x/connectors/translator-ldap/src/main/java/org/teiid/translator/ldap/LDAPSyncQueryExecution.java
branches/7.4.x/documentation/reference/src/main/docbook/en-US/content/translators.xml
Log:
TEIID-1659 adding pagination support for ldap
Modified: branches/7.4.x/build/kits/jboss-container/teiid-releasenotes.html
===================================================================
--- branches/7.4.x/build/kits/jboss-container/teiid-releasenotes.html 2011-08-01 18:58:02 UTC (rev 3356)
+++ branches/7.4.x/build/kits/jboss-container/teiid-releasenotes.html 2011-08-03 15:13:06 UTC (rev 3357)
@@ -69,6 +69,7 @@
<LI><B>Sync at Start</B> - When a node is restarted in a cluster, at end of start cycle Teiid will asynchronously fetch the cached internal materialized view contents from other nodes.
</UL>
</LI>
+ <LI><B>LDAP Pagination</B> - the ldap translator now supports pagination for retrieving large results from directory servers like Active Directory and OpenLDAP.
</UL>
<h2><a name="Compatibility">Compatibility Issues</a></h2>
Modified: branches/7.4.x/connectors/translator-ldap/src/main/java/org/teiid/translator/ldap/LDAPExecutionFactory.java
===================================================================
--- branches/7.4.x/connectors/translator-ldap/src/main/java/org/teiid/translator/ldap/LDAPExecutionFactory.java 2011-08-01 18:58:02 UTC (rev 3356)
+++ branches/7.4.x/connectors/translator-ldap/src/main/java/org/teiid/translator/ldap/LDAPExecutionFactory.java 2011-08-03 15:13:06 UTC (rev 3357)
@@ -53,6 +53,7 @@
private String searchDefaultBaseDN;
private boolean restrictToObjectClass;
private SearchDefaultScope searchDefaultScope = SearchDefaultScope.ONELEVEL_SCOPE;
+ private boolean usePagination;
public LDAPExecutionFactory() {
this.setMaxInCriteriaSize(1000);
@@ -89,7 +90,7 @@
@Override
public ResultSetExecution createResultSetExecution(QueryExpression command,ExecutionContext executionContext, RuntimeMetadata metadata, LdapContext context)
throws TranslatorException {
- return new LDAPSyncQueryExecution((Select)command, this, context);
+ return new LDAPSyncQueryExecution((Select)command, this, executionContext, context);
}
@Override
@@ -142,5 +143,15 @@
@Override
public boolean supportsNotCriteria() {
return true;
+ }
+
+ @TranslatorProperty(display="Use Pagination", description="Use a PagedResultsControl to page through large results. This is not supported by all directory servers.")
+ public boolean usePagination() {
+ return usePagination;
}
+
+ public void setUsePagination(boolean usePagination) {
+ this.usePagination = usePagination;
+ }
+
}
Modified: branches/7.4.x/connectors/translator-ldap/src/main/java/org/teiid/translator/ldap/LDAPSyncQueryExecution.java
===================================================================
--- branches/7.4.x/connectors/translator-ldap/src/main/java/org/teiid/translator/ldap/LDAPSyncQueryExecution.java 2011-08-01 18:58:02 UTC (rev 3356)
+++ branches/7.4.x/connectors/translator-ldap/src/main/java/org/teiid/translator/ldap/LDAPSyncQueryExecution.java 2011-08-03 15:13:06 UTC (rev 3357)
@@ -91,6 +91,8 @@
import javax.naming.directory.SearchResult;
import javax.naming.ldap.Control;
import javax.naming.ldap.LdapContext;
+import javax.naming.ldap.PagedResultsControl;
+import javax.naming.ldap.PagedResultsResponseControl;
import javax.naming.ldap.SortControl;
import javax.naming.ldap.SortKey;
@@ -98,6 +100,7 @@
import org.teiid.logging.LogConstants;
import org.teiid.logging.LogManager;
import org.teiid.metadata.Column;
+import org.teiid.translator.ExecutionContext;
import org.teiid.translator.ResultSetExecution;
import org.teiid.translator.TranslatorException;
import org.teiid.translator.TypeFacility;
@@ -119,6 +122,8 @@
private IQueryToLdapSearchParser parser;
private Select query;
private LDAPExecutionFactory executionFactory;
+ private ExecutionContext executionContext;
+ private SearchControls ctrls;
/**
* Constructor
@@ -127,10 +132,11 @@
* @param logger the ConnectorLogger
* @param ldapCtx the LDAP Context
*/
- public LDAPSyncQueryExecution(Select query, LDAPExecutionFactory factory, LdapContext ldapCtx) {
+ public LDAPSyncQueryExecution(Select query, LDAPExecutionFactory factory, ExecutionContext context, LdapContext ldapCtx) {
this.ldapConnection = ldapCtx;
this.query = query;
this.executionFactory = factory;
+ this.executionContext = context;
}
/**
@@ -146,31 +152,40 @@
// Create and configure the new search context.
createSearchContext();
- SearchControls ctrls = setSearchControls();
- setStandardRequestControls();
+ ctrls = setSearchControls();
+ String ctxName = searchDetails.getContextName();
+ String filter = searchDetails.getContextFilter();
+ if (ctxName == null || filter == null || ctrls == null) {
+ throw new TranslatorException(LogConstants.CTX_CONNECTOR, "Search context, filter, or controls were null. Cannot execute search."); //$NON-NLS-1$
+ }
+ setRequestControls(null);
// Execute the search.
- executeSearch(ctrls);
+ executeSearch();
}
/**
* Set the standard request controls
*/
- private void setStandardRequestControls() throws TranslatorException {
- Control[] sortCtrl = new Control[1];
+ private void setRequestControls(byte[] cookie) throws TranslatorException {
+ List<Control> ctrl = new ArrayList<Control>();
SortKey[] keys = searchDetails.getSortKeys();
- if (keys != null) {
- try {
- sortCtrl[0] = new SortControl(keys, Control.NONCRITICAL);
- this.ldapCtx.setRequestControls(sortCtrl);
- LogManager.logTrace(LogConstants.CTX_CONNECTOR, "Sort ordering was requested, and sort control was created successfully."); //$NON-NLS-1$
- } catch (NamingException ne) {
- final String msg = LDAPPlugin.Util.getString("LDAPSyncQueryExecution.setControlsError") + //$NON-NLS-1$
- " : "+ne.getExplanation(); //$NON-NLS-1$
- throw new TranslatorException(msg);
- } catch(IOException e) {
- final String msg = LDAPPlugin.Util.getString("LDAPSyncQueryExecution.setControlsError"); //$NON-NLS-1$
- throw new TranslatorException(e,msg);
+ try {
+ if (keys != null) {
+ ctrl.add(new SortControl(keys, Control.NONCRITICAL));
}
+ if (this.executionFactory.usePagination()) {
+ ctrl.add(new PagedResultsControl(this.executionContext.getBatchSize(), cookie, Control.CRITICAL));
+ }
+ if (!ctrl.isEmpty()) {
+ this.ldapCtx.setRequestControls(ctrl.toArray(new Control[ctrl.size()]));
+ LogManager.logTrace(LogConstants.CTX_CONNECTOR, "Sort/pagination controls were created successfully."); //$NON-NLS-1$
+ }
+ } catch (NamingException ne) {
+ final String msg = LDAPPlugin.Util.getString("LDAPSyncQueryExecution.setControlsError") + //$NON-NLS-1$
+ " : "+ne.getExplanation(); //$NON-NLS-1$
+ throw new TranslatorException(ne, msg);
+ } catch(IOException e) {
+ throw new TranslatorException(e);
}
}
@@ -219,22 +234,14 @@
* Perform the LDAP search against the subcontext, using the filter and
* search controls appropriate to the query and model metadata.
*/
- private void executeSearch(SearchControls ctrls) throws TranslatorException {
- String ctxName = searchDetails.getContextName();
+ private void executeSearch() throws TranslatorException {
String filter = searchDetails.getContextFilter();
- if (ctxName == null || filter == null || ctrls == null) {
- LogManager.logError(LogConstants.CTX_CONNECTOR, "Search context, filter, or controls were null. Cannot execute search."); //$NON-NLS-1$
- }
try {
searchEnumeration = this.ldapCtx.search("", filter, ctrls); //$NON-NLS-1$
} catch (NamingException ne) {
- LogManager.logError(LogConstants.CTX_CONNECTOR, "LDAP search failed. Attempted to search context " //$NON-NLS-1$
- + ctxName + " using filter " + filter); //$NON-NLS-1$
final String msg = LDAPPlugin.Util.getString("LDAPSyncQueryExecution.execSearchError"); //$NON-NLS-1$
- throw new TranslatorException(msg + " : " + ne.getExplanation()); //$NON-NLS-1$
+ throw new TranslatorException(ne, msg + " : " + ne.getExplanation()); //$NON-NLS-1$
} catch(Exception e) {
- LogManager.logError(LogConstants.CTX_CONNECTOR, "LDAP search failed. Attempted to search context " //$NON-NLS-1$
- + ctxName + " using filter " + filter); //$NON-NLS-1$
final String msg = LDAPPlugin.Util.getString("LDAPSyncQueryExecution.execSearchError"); //$NON-NLS-1$
throw new TranslatorException(e, msg);
}
@@ -294,6 +301,27 @@
SearchResult searchResult = (SearchResult) searchEnumeration.next();
result = getRow(searchResult);
}
+
+ if (result == null && this.executionFactory.usePagination()) {
+ byte[] cookie = null;
+ Control[] controls = ldapCtx.getResponseControls();
+ if (controls != null) {
+ for (int i = 0; i < controls.length; i++) {
+ if (controls[i] instanceof PagedResultsResponseControl) {
+ PagedResultsResponseControl prrc = (PagedResultsResponseControl)controls[i];
+ cookie = prrc.getCookie();
+ }
+ }
+ }
+
+ if (cookie == null) {
+ return null;
+ }
+
+ setRequestControls(cookie);
+ executeSearch();
+ return next();
+ }
return result;
} catch (SizeLimitExceededException e) {
@@ -451,22 +479,4 @@
}
}
-
- /**
- * Active Directory and OpenLDAP supports PagedResultsControls, so I left
- * this method in here in case we decide to extend support for this control
- * in the future.
- */
-// private void setADRequestControls(int maxBatchSize) {
-// try {
-// ldapCtx.setRequestControls(new Control[] { new PagedResultsControl(
-// maxBatchSize, Control.CRITICAL) });
-// } catch (NamingException ne) {
-// logger.logError("Failed to set page size for LDAP results. Please ensure that paged results controls are supported by the LDAP server implementation."); //$NON-NLS-1$
-// ne.printStackTrace();
-// } catch (IOException ioe) {
-// logger.logError("IO Exception while setting paged results control."); //$NON-NLS-1$
-// ioe.printStackTrace();
-// }
-// }
}
Modified: branches/7.4.x/documentation/reference/src/main/docbook/en-US/content/translators.xml
===================================================================
--- branches/7.4.x/documentation/reference/src/main/docbook/en-US/content/translators.xml 2011-08-01 18:58:02 UTC (rev 3356)
+++ branches/7.4.x/documentation/reference/src/main/docbook/en-US/content/translators.xml 2011-08-03 15:13:06 UTC (rev 3357)
@@ -545,6 +545,11 @@
<entry>Restrict Searches to objectClass named in the Name field for a table</entry>
<entry>false</entry>
</row>
+ <row>
+ <entry>UsePagination</entry>
+ <entry>Use a PagedResultsControl to page through large results. This is not supported by all directory servers.</entry>
+ <entry>false</entry>
+ </row>
</tbody>
</tgroup>
</table>
14 years, 8 months
teiid SVN: r3356 - in branches/7.4.x/documentation: reference/src/main/docbook/en-US/content and 1 other directory.
by teiid-commits@lists.jboss.org
Author: shawkins
Date: 2011-08-01 14:58:02 -0400 (Mon, 01 Aug 2011)
New Revision: 3356
Modified:
branches/7.4.x/documentation/caching-guide/src/main/docbook/en-US/content/codetable.xml
branches/7.4.x/documentation/reference/src/main/docbook/en-US/content/scalar_functions.xml
Log:
TEIID-1692 refined lookup docs
Modified: branches/7.4.x/documentation/caching-guide/src/main/docbook/en-US/content/codetable.xml
===================================================================
--- branches/7.4.x/documentation/caching-guide/src/main/docbook/en-US/content/codetable.xml 2011-08-01 16:08:41 UTC (rev 3355)
+++ branches/7.4.x/documentation/caching-guide/src/main/docbook/en-US/content/codetable.xml 2011-08-01 18:58:02 UTC (rev 3356)
@@ -29,7 +29,7 @@
<para>See the Reference for more information on use of the lookup function.</para>
<example>
<title>Country Code Lookup</title>
- <programlisting>lookup(‘ISOCountryCodes, ‘CountryName’, ‘CountryCode’, ‘US’)</programlisting>
+ <programlisting>lookup('ISOCountryCodes', 'CountryName', 'CountryCode', 'US')</programlisting>
</example>
</section>
<section>
@@ -47,7 +47,12 @@
</section>
<section>
<title>Materialized View Alternative</title>
- <para>The lookup function is a shortcut to create an internal materialized view. In many situations, it may be better to directly create the analogous materialized view rather than to use a code table.</para>
+ <para>The lookup function is a shortcut to create an internal materialized view with an appropriate primary key. In many situations, it may be better to directly create the analogous materialized view rather than to use a code table.</para>
+ <example>
+ <title>Country Code Lookup Against A Mat View</title>
+ <programlisting>SELECT (SELECT CountryCode From MatISOCountryCodes WHERE CountryName = tbl.CountryName) as cc FROM tbl</programlisting>
+ <para>Here MatISOCountryCodes is a view selecting from ISOCountryCodes that has been marked as materialized and has a primary key or index on CountryName. The scalar subquery will use the index to lookup the country code for each country name in tbl.</para>
+ </example>
<itemizedlist>
<title>Reasons to use a materialized view:</title>
<listitem>
@@ -63,7 +68,7 @@
<para>The ability to use <link linkend="nocache">OPTION NOCACHE</link>.</para>
</listitem>
<listitem>
- <para>Usage of a materialized view lookup as an uncorrelated subquery is no different than the use of the lookup function.</para>
+ <para>There is almost no performance difference.</para>
</listitem>
</itemizedlist>
<orderedlist>
@@ -72,7 +77,7 @@
<para>Create a view selecting the appropriate columns from the desired table. In general, this view may have an arbitrarily complicated transformation query.</para>
</listitem>
<listitem>
- <para>Designate the appropriate column(s) as the primary key.</para>
+ <para>Designate the appropriate column(s) as the primary key. Additional indexes can be added if needed.</para>
</listitem>
<listitem>
<para>Set the materialized property to true.</para>
Modified: branches/7.4.x/documentation/reference/src/main/docbook/en-US/content/scalar_functions.xml
===================================================================
--- branches/7.4.x/documentation/reference/src/main/docbook/en-US/content/scalar_functions.xml 2011-08-01 16:08:41 UTC (rev 3355)
+++ branches/7.4.x/documentation/reference/src/main/docbook/en-US/content/scalar_functions.xml 2011-08-01 18:58:02 UTC (rev 3356)
@@ -1795,20 +1795,21 @@
<para><synopsis>LOOKUP(codeTable, returnColumn, keyColumn, keyValue)</synopsis></para>
<para>In the lookup table codeTable, find the row where
keyColumn has the value keyValue and return the
- associated returnColumn. codeTable must be a fully-qualified string
- literal containing metadata identifiers, keyValue datatype
- must match datatype of the keyColumn, return datatype
- matches that of returnColumn. returnColumn and
- keyColumn parameters should use their shortened names.
+ associated returnColumn value or null if no matching key is found. codeTable must be a string literal that is the fully-qualified name of the target table.
+ returnColumn and key Column must also be string literals of just the relevant column names.
+ The keyValue can be any expression that must match the datatype of the keyColumn. The return datatype
+ matches that of returnColumn.
</para>
- <para>For example, a StatePostalCodes table used to translate postal codes to
- complete state names might represent an example of this type of
- lookup table. One column, PostalCode, represents a key column.
- Other tables refer to this two-letter code. A
- second column, StateDisplayName, would represent the complete name
- of the state. Hence, a query to this lookup table would typically
- provide the PostalCode and expect the StateDisplayName in response.
- </para>
+ <example>
+ <title>Country Code Lookup</title>
+ <programlisting>lookup('ISOCountryCodes', 'CountryName', 'CountryCode', 'US')</programlisting>
+ <para>A ISOCountryCodes table used to translate country name to
+ ISO codes. One column, CountryName, represents a key column.
+ A second column, CountryCode, would represent the ISO code of the country.
+ Hence, a query to this lookup table would
+ provide a CountryName, shown above as 'US', and expect a CountryCode value in response.
+ </para>
+ </example>
<para>When you call this function for any combination of codeTable, returnColumn, and
keyColumn for the first time, the Teiid System caches the result.
The Teiid System uses this cache for all
@@ -1817,6 +1818,7 @@
the Teiid System. Thus, you should not use this function for
data that is subject to updates. Instead, you can use it against
static data that does not change over time.</para>
+ <para>See the Caching Guide for more on the caching aspects of the lookup function.</para>
<note>
<itemizedlist>
<listitem>
14 years, 8 months
teiid SVN: r3355 - in branches/7.4.x/engine/src: main/java/org/teiid/query/metadata and 6 other directories.
by teiid-commits@lists.jboss.org
Author: shawkins
Date: 2011-08-01 12:08:41 -0400 (Mon, 01 Aug 2011)
New Revision: 3355
Added:
branches/7.4.x/engine/src/main/java/org/teiid/query/tempdata/AlterTempTable.java
Modified:
branches/7.4.x/engine/src/main/java/org/teiid/query/mapping/xml/ResultSetInfo.java
branches/7.4.x/engine/src/main/java/org/teiid/query/metadata/TempMetadataAdapter.java
branches/7.4.x/engine/src/main/java/org/teiid/query/optimizer/relational/rules/RuleMergeCriteria.java
branches/7.4.x/engine/src/main/java/org/teiid/query/optimizer/xml/XMLPlanToProcessVisitor.java
branches/7.4.x/engine/src/main/java/org/teiid/query/optimizer/xml/XMLPlanner.java
branches/7.4.x/engine/src/main/java/org/teiid/query/optimizer/xml/XMLPlannerEnvironment.java
branches/7.4.x/engine/src/main/java/org/teiid/query/optimizer/xml/XMLQueryPlanner.java
branches/7.4.x/engine/src/main/java/org/teiid/query/optimizer/xml/XMLStagaingQueryPlanner.java
branches/7.4.x/engine/src/main/java/org/teiid/query/processor/xml/ExecSqlInstruction.java
branches/7.4.x/engine/src/main/java/org/teiid/query/processor/xml/ExecStagingTableInstruction.java
branches/7.4.x/engine/src/main/java/org/teiid/query/processor/xml/RelationalPlanExecutor.java
branches/7.4.x/engine/src/main/java/org/teiid/query/processor/xml/XMLProcessorEnvironment.java
branches/7.4.x/engine/src/main/java/org/teiid/query/resolver/command/InsertResolver.java
branches/7.4.x/engine/src/main/java/org/teiid/query/tempdata/TempTableDataManager.java
branches/7.4.x/engine/src/test/java/org/teiid/query/processor/xml/TestXMLPlanningEnhancements.java
branches/7.4.x/engine/src/test/java/org/teiid/query/processor/xml/TestXMLProcessor.java
Log:
TEIID-1691 using dependent join planning to improve xml document model staging
Modified: branches/7.4.x/engine/src/main/java/org/teiid/query/mapping/xml/ResultSetInfo.java
===================================================================
--- branches/7.4.x/engine/src/main/java/org/teiid/query/mapping/xml/ResultSetInfo.java 2011-07-30 18:54:08 UTC (rev 3354)
+++ branches/7.4.x/engine/src/main/java/org/teiid/query/mapping/xml/ResultSetInfo.java 2011-08-01 16:08:41 UTC (rev 3355)
@@ -23,11 +23,13 @@
package org.teiid.query.mapping.xml;
import java.util.HashSet;
+import java.util.List;
import java.util.Set;
import org.teiid.query.processor.ProcessorPlan;
import org.teiid.query.sql.lang.Command;
import org.teiid.query.sql.lang.Criteria;
+import org.teiid.query.sql.lang.Insert;
import org.teiid.query.sql.lang.OrderBy;
import org.teiid.query.sql.symbol.ElementSymbol;
@@ -61,21 +63,21 @@
private boolean criteriaRaised = false;
- private boolean stagedResult = false;
-
- //joined source node state
- private int mappingClassNumber = 0;
private ElementSymbol mappingClassSymbol;
private boolean inputSet;
private boolean isCritNullDependent;
+
+ //auto-staging related info
+ private String stagingRoot;
+ private String tempTable;
+ private Command tempSelect;
+ private Insert tempInsert;
+ private Command tempDrop;
+ private boolean isAutoStaged;
+ private List<ElementSymbol> fkColumns;
public ResultSetInfo(String resultName) {
- this(resultName, false);
- }
-
- public ResultSetInfo(String resultName, boolean staged) {
this.resultSetName = resultName;
- this.stagedResult = staged;
}
public String getResultSetName() {
@@ -144,14 +146,19 @@
}
public Object clone() {
- ResultSetInfo clone = new ResultSetInfo(this.resultSetName, this.stagedResult);
+ ResultSetInfo clone = new ResultSetInfo(this.resultSetName);
clone.rsPlan = this.rsPlan;
clone.userRowLimit = this.userRowLimit;
clone.exceptionOnRowLimit = this.exceptionOnRowLimit;
clone.rsCommand = (Command)this.rsCommand.clone();
clone.criteriaRaised = this.criteriaRaised;
- clone.mappingClassNumber = this.mappingClassNumber;
clone.mappingClassSymbol = this.mappingClassSymbol;
+ clone.tempInsert = this.tempInsert;
+ clone.tempSelect = this.tempSelect;
+ clone.tempTable = this.tempTable;
+ clone.tempDrop = this.tempDrop;
+ clone.isAutoStaged = this.isAutoStaged;
+ clone.fkColumns = this.fkColumns;
return clone;
}
@@ -159,14 +166,6 @@
return resultSetName + ", resultSetObject " + rsCommand; //$NON-NLS-1$
}
- public int getMappingClassNumber() {
- return this.mappingClassNumber;
- }
-
- public void setMappingClassNumber(int mappingClassNumber) {
- this.mappingClassNumber = mappingClassNumber;
- }
-
public ElementSymbol getMappingClassSymbol() {
return this.mappingClassSymbol;
}
@@ -175,10 +174,6 @@
this.mappingClassSymbol = mappingClassSymbol;
}
- public boolean isStagedResult() {
- return this.stagedResult;
- }
-
public boolean hasInputSet() {
return inputSet;
}
@@ -194,4 +189,60 @@
public boolean isCritNullDependent(){
return this.isCritNullDependent;
}
+
+ public String getStagingRoot() {
+ return stagingRoot;
+ }
+
+ public void setStagingRoot(String stagingRoot) {
+ this.stagingRoot = stagingRoot;
+ }
+
+ public void setTempSelect(Command tempSelect) {
+ this.tempSelect = tempSelect;
+ }
+
+ public Command getTempSelect() {
+ return tempSelect;
+ }
+
+ public void setTempInsert(Insert tempInsert) {
+ this.tempInsert = tempInsert;
+ }
+
+ public Insert getTempInsert() {
+ return tempInsert;
+ }
+
+ public Command getTempDrop() {
+ return tempDrop;
+ }
+
+ public void setTempDrop(Command tempDrop) {
+ this.tempDrop = tempDrop;
+ }
+
+ public String getTempTable() {
+ return tempTable;
+ }
+
+ public void setTempTable(String rsTempTable) {
+ this.tempTable = rsTempTable;
+ }
+
+ public boolean isAutoStaged() {
+ return isAutoStaged;
+ }
+
+ public void setAutoStaged(boolean isAutoStaged) {
+ this.isAutoStaged = isAutoStaged;
+ }
+
+ public void setFkColumns(List<ElementSymbol> fkColumns) {
+ this.fkColumns = fkColumns;
+ }
+
+ public List<ElementSymbol> getFkColumns() {
+ return this.fkColumns;
+ }
}
Modified: branches/7.4.x/engine/src/main/java/org/teiid/query/metadata/TempMetadataAdapter.java
===================================================================
--- branches/7.4.x/engine/src/main/java/org/teiid/query/metadata/TempMetadataAdapter.java 2011-07-30 18:54:08 UTC (rev 3354)
+++ branches/7.4.x/engine/src/main/java/org/teiid/query/metadata/TempMetadataAdapter.java 2011-08-01 16:08:41 UTC (rev 3355)
@@ -325,7 +325,7 @@
return true;
}
- if(groupID instanceof TempMetadataID) {
+ if(groupID instanceof TempMetadataID && !(actualMetadata instanceof TempMetadataAdapter)) {
return false;
}
@@ -347,7 +347,7 @@
}
}
- if(groupID instanceof TempMetadataID) {
+ if(groupID instanceof TempMetadataID && !(actualMetadata instanceof TempMetadataAdapter)) {
return null;
}
Modified: branches/7.4.x/engine/src/main/java/org/teiid/query/optimizer/relational/rules/RuleMergeCriteria.java
===================================================================
--- branches/7.4.x/engine/src/main/java/org/teiid/query/optimizer/relational/rules/RuleMergeCriteria.java 2011-07-30 18:54:08 UTC (rev 3354)
+++ branches/7.4.x/engine/src/main/java/org/teiid/query/optimizer/relational/rules/RuleMergeCriteria.java 2011-08-01 16:08:41 UTC (rev 3355)
@@ -420,6 +420,7 @@
result.not = exists.isNegated();
//the correlations can only be in where (if no group by or aggregates) or having
result.mergeJoin = exists.getSubqueryHint().isMergeJoin();
+ result.makeInd = exists.getSubqueryHint().isDepJoin();
if (!UNNEST && !result.mergeJoin) {
return result;
}
Modified: branches/7.4.x/engine/src/main/java/org/teiid/query/optimizer/xml/XMLPlanToProcessVisitor.java
===================================================================
--- branches/7.4.x/engine/src/main/java/org/teiid/query/optimizer/xml/XMLPlanToProcessVisitor.java 2011-07-30 18:54:08 UTC (rev 3354)
+++ branches/7.4.x/engine/src/main/java/org/teiid/query/optimizer/xml/XMLPlanToProcessVisitor.java 2011-08-01 16:08:41 UTC (rev 3355)
@@ -22,6 +22,8 @@
package org.teiid.query.optimizer.xml;
+import java.util.HashMap;
+import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Stack;
@@ -70,7 +72,7 @@
Stack<Program> programStack = new Stack<Program>();
XMLPlannerEnvironment planEnv;
Program originalProgram ;
- Program cleanupProgram = new Program();
+ Map<String, List<String>> unloadInstructions = new HashMap<String, List<String>>();
public XMLPlanToProcessVisitor(XMLPlannerEnvironment env) {
this.planEnv = env;
@@ -85,8 +87,7 @@
// remove the current program from the stack; we no longer need this
originalProgram=this.programStack.pop();
- // cleanup program will have instructions to unload the staging table.
- originalProgram.addInstructions(cleanupProgram);
+ addUnloads(originalProgram, null);
}
public void start(MappingAttribute attribute, Map context){
@@ -289,7 +290,6 @@
Program currentProgram = programStack.peek();
String source = node.getActualResultSetName();
- ResultSetInfo info= node.getResultSetInfo();
// move to next row.
currentProgram.addInstruction(new MoveCursorInstruction(source));
@@ -327,15 +327,22 @@
}
List<String> stagingTables = node.getStagingTables();
+ Program currentProgram = programStack.peek();
+
for (String table : stagingTables) {
- Program currentProgram = programStack.peek();
-
// load staging
- currentProgram.addInstruction(new ExecStagingTableInstruction(table, planEnv.getStagingTableResultsInfo(table)));
+ ResultSetInfo stagingTableResultsInfo = planEnv.getStagingTableResultsInfo(table);
+ currentProgram.addInstruction(new ExecStagingTableInstruction(table, stagingTableResultsInfo));
// unload staging
String unloadName = planEnv.unLoadResultName(table);
- cleanupProgram.addInstruction(new ExecStagingTableInstruction(unloadName, planEnv.getStagingTableResultsInfo(unloadName)));
+ String parent = stagingTableResultsInfo.getStagingRoot();
+ List<String> instructions = this.unloadInstructions.get(parent);
+ if (instructions == null) {
+ instructions = new LinkedList<String>();
+ this.unloadInstructions.put(parent, instructions);
+ }
+ instructions.add(unloadName);
} // for
}
@@ -344,7 +351,22 @@
// stop recording and update the program
endRootRecursive(node, context);
}
+
+ Program currentProgram = programStack.peek();
+ if (node instanceof MappingSourceNode) {
+ String name = node.getSource();
+ addUnloads(currentProgram, name);
+ }
}
+
+ private void addUnloads(Program currentProgram, String name) {
+ List<String> unloads = this.unloadInstructions.get(name);
+ if (unloads != null) {
+ for (String string : unloads) {
+ currentProgram.addInstruction(new ExecStagingTableInstruction(string, planEnv.getStagingTableResultsInfo(string)));
+ }
+ }
+ }
public void start(final MappingRecursiveElement element, Map context){
Program currentProgram = programStack.peek();
Modified: branches/7.4.x/engine/src/main/java/org/teiid/query/optimizer/xml/XMLPlanner.java
===================================================================
--- branches/7.4.x/engine/src/main/java/org/teiid/query/optimizer/xml/XMLPlanner.java 2011-07-30 18:54:08 UTC (rev 3354)
+++ branches/7.4.x/engine/src/main/java/org/teiid/query/optimizer/xml/XMLPlanner.java 2011-08-01 16:08:41 UTC (rev 3355)
@@ -226,8 +226,8 @@
}
static void removeExcluded(MappingNode node) {
- for (Iterator i = node.getChildren().iterator(); i.hasNext();) {
- MappingNode child = (MappingNode)i.next();
+ for (Iterator<MappingNode> i = node.getChildren().iterator(); i.hasNext();) {
+ MappingNode child = i.next();
if (!(node instanceof MappingRecursiveElement) && child.isExcluded()) {
i.remove();
} else {
@@ -305,7 +305,7 @@
by = new OrderBy();
}
ElementSymbol mappedSymbol = (ElementSymbol)sourceNode.getSymbolMap().get(new ElementSymbol(elementNode.getNameInSource()));
- by.addVariable(mappedSymbol.clone(), ((Boolean)types.get(i)).booleanValue());
+ by.addVariable(mappedSymbol.clone(), types.get(i));
rs.setOrderBy(by);
}
}
Modified: branches/7.4.x/engine/src/main/java/org/teiid/query/optimizer/xml/XMLPlannerEnvironment.java
===================================================================
--- branches/7.4.x/engine/src/main/java/org/teiid/query/optimizer/xml/XMLPlannerEnvironment.java 2011-07-30 18:54:08 UTC (rev 3354)
+++ branches/7.4.x/engine/src/main/java/org/teiid/query/optimizer/xml/XMLPlannerEnvironment.java 2011-08-01 16:08:41 UTC (rev 3355)
@@ -124,7 +124,7 @@
public ResultSetInfo getStagingTableResultsInfo(String groupName) {
ResultSetInfo info = (ResultSetInfo)this.stagingResultsInfo.get(groupName.toUpperCase());
if (info == null) {
- info = new ResultSetInfo(groupName, true);
+ info = new ResultSetInfo(groupName);
this.stagingResultsInfo.put(info.getResultSetName().toUpperCase(), info);
}
return info;
Modified: branches/7.4.x/engine/src/main/java/org/teiid/query/optimizer/xml/XMLQueryPlanner.java
===================================================================
--- branches/7.4.x/engine/src/main/java/org/teiid/query/optimizer/xml/XMLQueryPlanner.java 2011-07-30 18:54:08 UTC (rev 3354)
+++ branches/7.4.x/engine/src/main/java/org/teiid/query/optimizer/xml/XMLQueryPlanner.java 2011-08-01 16:08:41 UTC (rev 3355)
@@ -55,7 +55,6 @@
import org.teiid.query.processor.relational.RelationalPlan;
import org.teiid.query.resolver.QueryResolver;
import org.teiid.query.resolver.util.ResolverUtil;
-import org.teiid.query.rewriter.QueryRewriter;
import org.teiid.query.sql.lang.Command;
import org.teiid.query.sql.lang.Criteria;
import org.teiid.query.sql.lang.Drop;
@@ -140,10 +139,10 @@
prepareQuery(sourceNode, planEnv, command);
- QueryUtil.rewriteQuery(command, planEnv.getGlobalMetadata(), planEnv.context);
+ Command cmd = QueryUtil.rewriteQuery(command, planEnv.getGlobalMetadata(), planEnv.context);
// Plan the result set.
- ProcessorPlan queryPlan = optimizePlan(command, planEnv);
+ ProcessorPlan queryPlan = optimizePlan(cmd, planEnv);
rsInfo.setPlan(queryPlan);
} catch (Exception e) {
throw new TeiidRuntimeException(e);
@@ -441,7 +440,7 @@
return finder.msn;
}
- private static void updateSymbolMap(Map symbolMap, String oldGroup, final String newGroup, QueryMetadataInterface metadata)
+ static void updateSymbolMap(Map symbolMap, String oldGroup, final String newGroup, QueryMetadataInterface metadata)
throws QueryResolverException,QueryMetadataException,TeiidComponentException {
GroupSymbol oldGroupSymbol = new GroupSymbol(oldGroup);
@@ -485,7 +484,7 @@
GroupSymbol srcGroup = QueryUtil.createResolvedGroup(srcGroupName, planEnv.getGlobalMetadata());
- String intoGroupName = "#"+stageGroupName.replace('.', '_'); //$NON-NLS-1$
+ String intoGroupName = getTempTableName(stageGroupName);
GroupSymbol intoGroupSymbol = new GroupSymbol(intoGroupName);
query.setInto(new Into(intoGroupSymbol));
@@ -571,6 +570,11 @@
return true;
}
+
+ static String getTempTableName(String stageGroupName) {
+ String intoGroupName = "#"+stageGroupName.replace('.', '_'); //$NON-NLS-1$
+ return intoGroupName;
+ }
/**
* This builds a command in the following form; If staging table name is "FOO"
Modified: branches/7.4.x/engine/src/main/java/org/teiid/query/optimizer/xml/XMLStagaingQueryPlanner.java
===================================================================
--- branches/7.4.x/engine/src/main/java/org/teiid/query/optimizer/xml/XMLStagaingQueryPlanner.java 2011-07-30 18:54:08 UTC (rev 3354)
+++ branches/7.4.x/engine/src/main/java/org/teiid/query/optimizer/xml/XMLStagaingQueryPlanner.java 2011-08-01 16:08:41 UTC (rev 3355)
@@ -22,23 +22,54 @@
package org.teiid.query.optimizer.xml;
+import java.util.ArrayList;
+import java.util.Arrays;
import java.util.Collection;
+import java.util.HashMap;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Map;
import org.teiid.api.exception.query.QueryMetadataException;
+import org.teiid.api.exception.query.QueryParserException;
import org.teiid.api.exception.query.QueryPlannerException;
import org.teiid.api.exception.query.QueryResolverException;
import org.teiid.core.TeiidComponentException;
import org.teiid.core.TeiidRuntimeException;
+import org.teiid.logging.LogConstants;
+import org.teiid.logging.LogManager;
import org.teiid.query.mapping.relational.QueryNode;
+import org.teiid.query.mapping.xml.MappingBaseNode;
import org.teiid.query.mapping.xml.MappingDocument;
+import org.teiid.query.mapping.xml.MappingNode;
import org.teiid.query.mapping.xml.MappingSourceNode;
import org.teiid.query.mapping.xml.MappingVisitor;
import org.teiid.query.mapping.xml.Navigator;
import org.teiid.query.mapping.xml.ResultSetInfo;
+import org.teiid.query.metadata.TempMetadataStore;
import org.teiid.query.optimizer.relational.RelationalPlanner;
+import org.teiid.query.parser.QueryParser;
+import org.teiid.query.resolver.QueryResolver;
+import org.teiid.query.resolver.util.ResolverUtil;
+import org.teiid.query.resolver.util.ResolverVisitor;
+import org.teiid.query.sql.lang.Command;
+import org.teiid.query.sql.lang.CompareCriteria;
+import org.teiid.query.sql.lang.Criteria;
+import org.teiid.query.sql.lang.ExistsCriteria;
+import org.teiid.query.sql.lang.From;
+import org.teiid.query.sql.lang.GroupBy;
+import org.teiid.query.sql.lang.Insert;
import org.teiid.query.sql.lang.Option;
import org.teiid.query.sql.lang.Query;
+import org.teiid.query.sql.lang.Select;
+import org.teiid.query.sql.lang.UnaryFromClause;
+import org.teiid.query.sql.symbol.Constant;
+import org.teiid.query.sql.symbol.ElementSymbol;
+import org.teiid.query.sql.symbol.ExpressionSymbol;
import org.teiid.query.sql.symbol.GroupSymbol;
+import org.teiid.query.sql.symbol.Reference;
+import org.teiid.query.sql.symbol.SingleElementSymbol;
+import org.teiid.query.sql.visitor.ExpressionMappingVisitor;
import org.teiid.query.sql.visitor.GroupCollectorVisitor;
@@ -47,7 +78,6 @@
*/
public class XMLStagaingQueryPlanner {
-
static void stageQueries(MappingDocument doc, final XMLPlannerEnvironment planEnv)
throws QueryPlannerException, QueryMetadataException, TeiidComponentException {
@@ -86,7 +116,7 @@
}
static boolean stagePlannedQuery(MappingSourceNode sourceNode, XMLPlannerEnvironment planEnv)
- throws QueryPlannerException, QueryMetadataException, TeiidComponentException, QueryResolverException {
+ throws QueryPlannerException, QueryMetadataException, TeiidComponentException, QueryResolverException, QueryParserException {
Option option = planEnv.xmlCommand.getOption();
@@ -114,18 +144,6 @@
return false;
}
- //id as mapping class
- Object metadataID = planEnv.getGlobalMetadata().getGroupID(sourceNode.getResultName());
- if (RelationalPlanner.isNoCacheGroup(planEnv.getGlobalMetadata(), metadataID, option)) {
- return false;
- }
-
- //id as generated mapping class name
- metadataID = planEnv.getGlobalMetadata().getGroupID(sourceNode.getActualResultSetName());
- if (RelationalPlanner.isNoCacheGroup(planEnv.getGlobalMetadata(), metadataID, option)) {
- return false;
- }
-
// get the original transformation of the mapping class before planning.
Query stagableQuery = (Query)QueryUtil.getQueryFromQueryNode(groupName, planEnv);
@@ -140,17 +158,192 @@
}
}
+ Criteria crit = ((Query)rsInfo.getCommand()).getCriteria();
+
+ GroupSymbol parent = null;
+ LinkedHashSet<ElementSymbol> outerReferences = new LinkedHashSet<ElementSymbol>();
+ LinkedHashSet<ElementSymbol> fkColumns = new LinkedHashSet<ElementSymbol>();
+ //see if we can perform a dependent join
+ for (Criteria conjunct : Criteria.separateCriteriaByAnd(crit)) {
+ if (!(conjunct instanceof CompareCriteria)) {
+ continue;
+ }
+ CompareCriteria cc = (CompareCriteria)conjunct;
+ if (cc.getOperator() != CompareCriteria.EQ) {
+ continue;
+ }
+ if (!(cc.getLeftExpression() instanceof ElementSymbol)
+ || !(cc.getRightExpression() instanceof ElementSymbol)) {
+ continue;
+ }
+ ElementSymbol les = (ElementSymbol)cc.getLeftExpression();
+ ElementSymbol res = (ElementSymbol)cc.getRightExpression();
+ if (les.getGroupSymbol().getNonCorrelationName().equalsIgnoreCase(groupName)) {
+ parent = res.getGroupSymbol();
+ outerReferences.add(res.clone());
+ fkColumns.add(les.clone());
+ } else if (res.getGroupSymbol().getNonCorrelationName().equalsIgnoreCase(groupName)) {
+ parent = les.getGroupSymbol();
+ outerReferences.add(les.clone());
+ fkColumns.add(res.clone());
+ }
+ }
+ String stagingGroupName = planEnv.getStagedResultName(groupName);
+
+ boolean recursive = false;
+ MappingSourceNode msn = sourceNode;
+ while (!recursive && msn != null) {
+ MappingNode mappingNode = msn.getChildren().get(0);
+ if (mappingNode instanceof MappingBaseNode) {
+ recursive = ((MappingBaseNode)mappingNode).isRootRecursiveNode();
+ }
+ msn = msn.getParentSourceNode();
+ }
+
+ if (parent != null && !recursive) {
+ stagableQuery = (Query)stagableQuery.clone();
+ String parentName = parent.getNonCorrelationName();
+
+ String parentStagingName = planEnv.getStagedResultName(parentName);
+ GroupSymbol parentTempTable = new GroupSymbol(XMLQueryPlanner.getTempTableName(parentStagingName));
+ ResultSetInfo parentRsInfo = planEnv.getStagingTableResultsInfo(parentStagingName);
+ String stagingRoot = sourceNode.getParentSourceNode().getSource();
+
+ boolean parentStaged = parentRsInfo.getPlan() != null;
+ //TODO: check to see if the parent was manually staged
+
+ if (!parentStaged) {
+ //TODO: if not a level 1 child we could use the old auto staging logic instead
+
+ //switch the parent over to the source
+ parentRsInfo = sourceNode.getParentSourceNode().getResultSetInfo();
+
+ if (parentRsInfo.getTempTable() == null) {
+ //create a temp table to represent the resultset
+ List<SingleElementSymbol> projectedSymbols = parentRsInfo.getCommand().getProjectedSymbols();
+ ArrayList<SingleElementSymbol> elements = new ArrayList<SingleElementSymbol>(projectedSymbols.size());
+ for (SingleElementSymbol singleElementSymbol : projectedSymbols) {
+ singleElementSymbol = (SingleElementSymbol) singleElementSymbol.clone();
+ ResolverVisitor.resolveLanguageObject(singleElementSymbol, planEnv.getGlobalMetadata());
+ elements.add(singleElementSymbol);
+ }
+ TempMetadataStore store = planEnv.getGlobalMetadata().getMetadataStore();
+ // create a new group name and to the temp store
+ GroupSymbol newGroup = new GroupSymbol(SourceNodePlannerVisitor.getNewName("#" + planEnv.getAliasName(parentName) + "_RS", store)); //$NON-NLS-1$ //$NON-NLS-2$
+ newGroup.setMetadataID(store.addTempGroup(newGroup.getName(), elements, false, true));
+
+ parentStagingName = newGroup.getName();
+ parentTempTable = newGroup;
+ } else {
+ parentStagingName = parentRsInfo.getTempTable();
+ parentTempTable = new GroupSymbol(parentRsInfo.getTempTable());
+ parentStaged = true;
+ }
+ } else {
+ stagingRoot = parentRsInfo.getStagingRoot();
+ }
+
+ Query query = new Query();
+ query.setSelect(new Select(Arrays.asList(new ExpressionSymbol("expr", new Constant(1))))); //$NON-NLS-1$
+
+ query.setFrom(new From(Arrays.asList(new UnaryFromClause(parentTempTable))));
+
+ Map symbolMap = new HashMap();
+ String inlineViewName = planEnv.getAliasName(rsInfo.getResultSetName());
+ XMLQueryPlanner.updateSymbolMap(symbolMap, rsInfo.getResultSetName(), inlineViewName, planEnv.getGlobalMetadata());
+ XMLQueryPlanner.updateSymbolMap(symbolMap, parentName, parentTempTable.getName(), planEnv.getGlobalMetadata());
+
+ crit = (Criteria) crit.clone();
+ ExpressionMappingVisitor.mapExpressions(crit, symbolMap);
+
+ if (!stagableQuery.getSelect().isDistinct()) {
+ query.setHaving(crit);
+ //group by is added so that subquery planning sees that we are distinct
+ query.setGroupBy(new GroupBy(new ArrayList<ElementSymbol>(outerReferences)));
+ ExpressionMappingVisitor.mapExpressions(query.getGroupBy(), symbolMap);
+ } else {
+ query.setCriteria(crit);
+ }
+ ExistsCriteria ec = new ExistsCriteria();
+ ec.setSubqueryHint(new ExistsCriteria.SubqueryHint());
+ ec.getSubqueryHint().setDepJoin(true);
+ ec.setCommand(query);
+ Criteria existing = stagableQuery.getCriteria();
+ stagableQuery.setCriteria(Criteria.combineCriteria(existing, ec));
+ if (!XMLQueryPlanner.planStagaingQuery(false, groupName, stagingGroupName, stagableQuery, planEnv)) {
+ return false;
+ }
+ if (!parentStaged) {
+ //need to associate temp load/get/drop with the rsinfo for use by the execsqlinstruction
+ Insert insert = new Insert();
+ insert.setGroup(parentTempTable);
+ int valCount = parentRsInfo.getCommand().getProjectedSymbols().size();
+ ArrayList<Reference> vals = new ArrayList<Reference>(valCount);
+ for (int i = 0; i < valCount; i++) {
+ vals.add(new Reference(i+1));
+ }
+ insert.setValues(vals);
+ QueryResolver.resolveCommand(insert, planEnv.getGlobalMetadata());
+
+ Command tempCommand = QueryParser.getQueryParser().parseCommand("select * from " + parentStagingName); //$NON-NLS-1$
+ QueryResolver.resolveCommand(tempCommand, planEnv.getGlobalMetadata());
+
+ Command dropCommand = QueryParser.getQueryParser().parseCommand("drop table " + parentStagingName); //$NON-NLS-1$
+ QueryResolver.resolveCommand(dropCommand, planEnv.getGlobalMetadata());
+
+ parentRsInfo.setTempTable(parentStagingName);
+ parentRsInfo.setTempSelect(tempCommand);
+ parentRsInfo.setTempInsert(insert);
+ parentRsInfo.setTempDrop(dropCommand);
+ }
+ LogManager.logDetail(LogConstants.CTX_XML_PLANNER, "Using a dependent join to load the mapping class", groupName); //$NON-NLS-1$
+ // add to the document that a staging table has been added
+ sourceNode.addStagingTable(stagingGroupName);
+ GroupSymbol tempGroup = new GroupSymbol(XMLQueryPlanner.getTempTableName(stagingGroupName));
+ ResolverUtil.resolveGroup(tempGroup, planEnv.getGlobalMetadata());
+ Collection<GroupSymbol> temp = Arrays.asList(tempGroup);
+ List<ElementSymbol> fk = new ArrayList<ElementSymbol>(fkColumns.size());
+ for (ElementSymbol elementSymbol : fkColumns) {
+ ElementSymbol es = new ElementSymbol(elementSymbol.getShortName());
+ ResolverVisitor.resolveLanguageObject(es, temp, planEnv.getGlobalMetadata());
+ fk.add(es);
+ }
+ ResultSetInfo stagedInfo = planEnv.getStagingTableResultsInfo(stagingGroupName);
+ stagedInfo.setStagingRoot(stagingRoot);
+ stagedInfo.setAutoStaged(true);
+ stagedInfo.setFkColumns(fk);
+ stagedInfo.setTempTable(tempGroup.getName());
+
+ rsInfo.setAutoStaged(true);
+ return true;
+ }
+
+ //id as mapping class
+ Object metadataID = planEnv.getGlobalMetadata().getGroupID(sourceNode.getResultName());
+ if (RelationalPlanner.isNoCacheGroup(planEnv.getGlobalMetadata(), metadataID, option)) {
+ return false;
+ }
+
+ //id as generated mapping class name
+ metadataID = planEnv.getGlobalMetadata().getGroupID(sourceNode.getActualResultSetName());
+ if (RelationalPlanner.isNoCacheGroup(planEnv.getGlobalMetadata(), metadataID, option)) {
+ return false;
+ }
+
stagableQuery = (Query)stagableQuery.clone();
-
+
// stage the transformation query and it is successful
- String stagingGroupName = planEnv.getStagedResultName(groupName);
if (!XMLQueryPlanner.planStagaingQuery(true, groupName, stagingGroupName, stagableQuery, planEnv)) {
return false;
}
// add to the document that a staging table has been added
sourceNode.addStagingTable(stagingGroupName);
-
+ ResultSetInfo stagedInfo = planEnv.getStagingTableResultsInfo(stagingGroupName);
+ stagedInfo.setAutoStaged(true);
+ stagedInfo.setTempTable(XMLQueryPlanner.getTempTableName(stagingGroupName));
+
+ rsInfo.setAutoStaged(true);
return true;
}
Modified: branches/7.4.x/engine/src/main/java/org/teiid/query/processor/xml/ExecSqlInstruction.java
===================================================================
--- branches/7.4.x/engine/src/main/java/org/teiid/query/processor/xml/ExecSqlInstruction.java 2011-07-30 18:54:08 UTC (rev 3354)
+++ branches/7.4.x/engine/src/main/java/org/teiid/query/processor/xml/ExecSqlInstruction.java 2011-08-01 16:08:41 UTC (rev 3355)
@@ -36,7 +36,7 @@
* Executes a SQL statement, defines a result set.
*/
public class ExecSqlInstruction extends ProcessorInstruction {
- private String resultSetName;
+ String resultSetName;
ResultSetInfo info;
public ExecSqlInstruction(String resultSetName, ResultSetInfo info) {
@@ -48,7 +48,16 @@
public XMLContext process(XMLProcessorEnvironment env, XMLContext context)
throws BlockedException, TeiidComponentException, TeiidProcessingException{
- LogManager.logTrace(org.teiid.logging.LogConstants.CTX_XML_PLAN, new Object[]{"SQL: Result set DOESN'T exist:",resultSetName}); //$NON-NLS-1$
+ execute(env, context);
+
+ env.incrementCurrentProgramCounter();
+ return context;
+ }
+
+ protected void execute(XMLProcessorEnvironment env, XMLContext context)
+ throws TeiidComponentException, BlockedException,
+ TeiidProcessingException {
+ LogManager.logTrace(org.teiid.logging.LogConstants.CTX_XML_PLAN, new Object[]{"SQL: Result set DOESN'T exist:",resultSetName}); //$NON-NLS-1$
PlanExecutor executor = getPlanExecutor(env, context);
// this execute can throw the blocked exception
@@ -60,10 +69,7 @@
// save this executioner in the context, so that all the nodes
// below can access the data.
context.setResultSet(this.resultSetName, executor);
-
- env.incrementCurrentProgramCounter();
- return context;
- }
+ }
public PlanExecutor getPlanExecutor(XMLProcessorEnvironment env,
XMLContext context) throws TeiidComponentException {
Modified: branches/7.4.x/engine/src/main/java/org/teiid/query/processor/xml/ExecStagingTableInstruction.java
===================================================================
--- branches/7.4.x/engine/src/main/java/org/teiid/query/processor/xml/ExecStagingTableInstruction.java 2011-07-30 18:54:08 UTC (rev 3354)
+++ branches/7.4.x/engine/src/main/java/org/teiid/query/processor/xml/ExecStagingTableInstruction.java 2011-08-01 16:08:41 UTC (rev 3355)
@@ -24,13 +24,10 @@
import static org.teiid.query.analysis.AnalysisRecord.*;
-import java.util.Map;
-
import org.teiid.client.plan.PlanNode;
import org.teiid.common.buffer.BlockedException;
import org.teiid.core.TeiidComponentException;
import org.teiid.core.TeiidProcessingException;
-import org.teiid.logging.LogManager;
import org.teiid.query.mapping.xml.ResultSetInfo;
@@ -38,20 +35,14 @@
/**
* This instruction is to start loading a staging table. The difference between the loading the
* staging table and execute sql node is that sql node will capture the results and save them in
- * the context object, where as staging does not care about the results, beacuse they are actully
+ * the context object, where as staging does not care about the results, because they are actually
* stored in the temp table store, will be accessed by required query directly from there, as these
* results are nothing do with producing the document directly.
- *
- * NOTE: In future we can improve this to load parallelly, if there are more than single
- * staging table defined on the mapping document
*/
-public class ExecStagingTableInstruction extends ProcessorInstruction {
- String resultSetName;
- ResultSetInfo info;
+public class ExecStagingTableInstruction extends ExecSqlInstruction {
public ExecStagingTableInstruction(String resultName, ResultSetInfo info) {
- this.resultSetName = resultName;
- this.info = info;
+ super(resultName, info);
}
/**
@@ -61,19 +52,8 @@
throws BlockedException, TeiidComponentException, TeiidProcessingException {
if (!env.isStagingTableLoaded(this.resultSetName)) {
- LogManager.logTrace(org.teiid.logging.LogConstants.CTX_XML_PLAN, new Object[]{"SQL: Result set DOESN'T exist:",resultSetName}); //$NON-NLS-1$
+ super.execute(env, context);
- PlanExecutor executor = context.getResultExecutor(resultSetName);
- if (executor == null) {
- executor = env.createResultExecutor(resultSetName, info);
- context.setResultExecutor(resultSetName, executor);
- }
-
- // this execute can throw the blocked exception; note that staging tables will not have any
- // bound references; they are not part of the document; so they do not know about document
- // details.
- Map referenceValues = null;
- executor.execute(referenceValues, false);
env.markStagingTableAsLoaded(this.resultSetName);
// now that we done executing the plan; remove the plan from context
Modified: branches/7.4.x/engine/src/main/java/org/teiid/query/processor/xml/RelationalPlanExecutor.java
===================================================================
--- branches/7.4.x/engine/src/main/java/org/teiid/query/processor/xml/RelationalPlanExecutor.java 2011-07-30 18:54:08 UTC (rev 3354)
+++ branches/7.4.x/engine/src/main/java/org/teiid/query/processor/xml/RelationalPlanExecutor.java 2011-08-01 16:08:41 UTC (rev 3355)
@@ -27,32 +27,53 @@
import org.teiid.common.buffer.BlockedException;
import org.teiid.common.buffer.BufferManager;
-import org.teiid.common.buffer.IndexedTupleSource;
+import org.teiid.common.buffer.TupleSource;
import org.teiid.core.TeiidComponentException;
import org.teiid.core.TeiidProcessingException;
+import org.teiid.logging.LogConstants;
import org.teiid.logging.LogManager;
import org.teiid.query.QueryPlugin;
import org.teiid.query.mapping.xml.ResultSetInfo;
+import org.teiid.query.metadata.TempMetadataAdapter;
import org.teiid.query.processor.BatchIterator;
import org.teiid.query.processor.ProcessorDataManager;
import org.teiid.query.processor.ProcessorPlan;
import org.teiid.query.processor.QueryProcessor;
+import org.teiid.query.sql.lang.Insert;
import org.teiid.query.sql.symbol.ElementSymbol;
import org.teiid.query.sql.util.VariableContext;
+import org.teiid.query.tempdata.AlterTempTable;
import org.teiid.query.util.CommandContext;
-
-
/**
* This is a helper class which can execute a supplied relational plan and supply
* resulting query results to the caller.
- * Note: in future we would want to replace this class with submitting the requests directly to
- * process worker queue.
*/
class RelationalPlanExecutor implements PlanExecutor {
- QueryProcessor internalProcessor;
+ private final class TempLoadTupleSource implements TupleSource {
+ @Override
+ public List<?> nextTuple() throws TeiidComponentException,
+ TeiidProcessingException {
+ try {
+ List<?> tuple = tupleSource.nextTuple();
+ if (tuple == null) {
+ doneLoading = true;
+ }
+ return tuple;
+ } catch (BlockedException e) {
+ return null;
+ }
+ }
+ @Override
+ public void closeSource() {
+ tupleSource.closeSource();
+ }
+ }
+
+ QueryProcessor internalProcessor;
+
// information about the result set.
ResultSetInfo resultInfo;
// buffer store
@@ -60,16 +81,20 @@
// flag to denote the end of rows
boolean endOfRows = false;
// results after the execution bucket.
- IndexedTupleSource tupleSource;
+ TupleSource tupleSource;
// cached current row of results.
- List currentRow;
+ List<?> currentRow;
int currentRowNumber = 0;
+ private ProcessorDataManager dataManager;
+ private boolean executed;
+ private boolean doneLoading;
public RelationalPlanExecutor (ResultSetInfo resultInfo, CommandContext context, ProcessorDataManager dataMgr, BufferManager bufferMgr)
throws TeiidComponentException{
this.resultInfo = resultInfo;
this.bufferMgr = bufferMgr;
+ this.dataManager = dataMgr;
ProcessorPlan plan = resultInfo.getPlan();
CommandContext subContext = context.clone();
@@ -97,9 +122,38 @@
internalProcessor.init();
}
}
- if (!openOnly) {
- //force execution
- this.tupleSource.hasNext();
+ if (!openOnly && !executed) {
+ String tempTable = this.resultInfo.getTempTable();
+ if (tempTable != null && !doneLoading && !this.resultInfo.isAutoStaged()) {
+ LogManager.logDetail(LogConstants.CTX_XML_PLAN, "Loading result set temp table", tempTable); //$NON-NLS-1$
+
+ Insert insert = this.resultInfo.getTempInsert();
+ insert.setTupleSource(new TempLoadTupleSource());
+ this.dataManager.registerRequest(this.internalProcessor.getContext(), insert, TempMetadataAdapter.TEMP_MODEL.getName(), null, 0, -1);
+ if (!doneLoading) {
+ throw BlockedException.block("Blocking on result set load"); //$NON-NLS-1$
+ }
+ internalProcessor.closeProcessing();
+ AlterTempTable att = new AlterTempTable(tempTable);
+ //mark the temp table as non-updatable
+ this.dataManager.registerRequest(this.internalProcessor.getContext(), att, TempMetadataAdapter.TEMP_MODEL.getName(), null, 0, -1);
+ this.tupleSource = this.dataManager.registerRequest(this.internalProcessor.getContext(), this.resultInfo.getTempSelect(), TempMetadataAdapter.TEMP_MODEL.getName(), null, 0, -1);
+ }
+ //force execution
+ currentRow();
+
+ if (this.resultInfo.isAutoStaged() && tempTable != null) {
+ AlterTempTable att = new AlterTempTable(tempTable);
+ int size = (Integer)this.currentRow.get(0);
+ if (size > this.bufferMgr.getProcessorBatchSize() * 2) {
+ //TODO: if the parent is small, then this is not necessary
+ att.setIndexColumns(this.resultInfo.getFkColumns());
+ }
+ this.dataManager.registerRequest(this.internalProcessor.getContext(), att, TempMetadataAdapter.TEMP_MODEL.getName(), null, 0, -1);
+ }
+
+ this.currentRowNumber = 0;
+ this.executed = true;
}
}
@@ -122,7 +176,9 @@
if (!endOfRows) {
// get the next row
- this.currentRow = this.tupleSource.nextTuple();
+ if (this.currentRow == null || this.currentRowNumber > 0) {
+ this.currentRow = this.tupleSource.nextTuple();
+ }
this.currentRowNumber++;
// check if we walked over the row limit
@@ -159,6 +215,19 @@
*/
public void close() throws TeiidComponentException {
this.internalProcessor.closeProcessing();
+ if (this.tupleSource != null) {
+ this.tupleSource.closeSource();
+ }
+ String rsTempTable = this.resultInfo.getTempTable();
+ if (rsTempTable != null) {
+ LogManager.logDetail(LogConstants.CTX_XML_PLAN, "Unloading result set temp table", rsTempTable); //$NON-NLS-1$
+ internalProcessor.closeProcessing();
+ try {
+ this.tupleSource = this.dataManager.registerRequest(this.internalProcessor.getContext(), this.resultInfo.getTempDrop(), TempMetadataAdapter.TEMP_MODEL.getName(), null, 0, -1);
+ } catch (TeiidProcessingException e) {
+ LogManager.logDetail(org.teiid.logging.LogConstants.CTX_XML_PLAN, e, "Error dropping result set temp table", rsTempTable); //$NON-NLS-1$
+ }
+ }
LogManager.logTrace(org.teiid.logging.LogConstants.CTX_XML_PLAN, new Object[]{"closed executor", resultInfo.getResultSetName()}); //$NON-NLS-1$
}
Modified: branches/7.4.x/engine/src/main/java/org/teiid/query/processor/xml/XMLProcessorEnvironment.java
===================================================================
--- branches/7.4.x/engine/src/main/java/org/teiid/query/processor/xml/XMLProcessorEnvironment.java 2011-07-30 18:54:08 UTC (rev 3354)
+++ branches/7.4.x/engine/src/main/java/org/teiid/query/processor/xml/XMLProcessorEnvironment.java 2011-08-01 16:08:41 UTC (rev 3355)
@@ -179,18 +179,25 @@
if (programState.programCounter >= programState.lookaheadCounter && instrs.size() > programState.programCounter + 1) {
for (programState.lookaheadCounter = programState.programCounter; programState.lookaheadCounter < instrs.size(); programState.lookaheadCounter++) {
ProcessorInstruction pi = instrs.get(programState.lookaheadCounter);
+ boolean staging = false;
if (pi instanceof ExecStagingTableInstruction) {
- //need to load staging tables prior to source queries
- break;
+ staging = true;
+ ExecStagingTableInstruction esti = (ExecStagingTableInstruction)pi;
+ if (!esti.info.isAutoStaged()) {
+ //need to load staging tables prior to source queries
+ break;
+ }
}
if (pi instanceof ExecSqlInstruction) {
ExecSqlInstruction esi = (ExecSqlInstruction)pi;
+ if (!staging && esi.info.isAutoStaged() && esi.info.getTempTable() == null) {
+ continue; //derived load
+ }
PlanExecutor pe = esi.getPlanExecutor(this, context);
pe.execute(context.getReferenceValues(), true);
}
}
}
-
return programState.program.getInstructionAt(programState.programCounter);
}
Modified: branches/7.4.x/engine/src/main/java/org/teiid/query/resolver/command/InsertResolver.java
===================================================================
--- branches/7.4.x/engine/src/main/java/org/teiid/query/resolver/command/InsertResolver.java 2011-07-30 18:54:08 UTC (rev 3354)
+++ branches/7.4.x/engine/src/main/java/org/teiid/query/resolver/command/InsertResolver.java 2011-08-01 16:08:41 UTC (rev 3355)
@@ -97,9 +97,9 @@
if (insert.getVariables().isEmpty()) {
if (insert.getGroup().isResolved()) {
- List variables = ResolverUtil.resolveElementsInGroup(insert.getGroup(), metadata);
- for (Iterator i = variables.iterator(); i.hasNext();) {
- insert.addVariable((ElementSymbol)((ElementSymbol)i.next()).clone());
+ List<ElementSymbol> variables = ResolverUtil.resolveElementsInGroup(insert.getGroup(), metadata);
+ for (Iterator<ElementSymbol> i = variables.iterator(); i.hasNext();) {
+ insert.addVariable(i.next().clone());
}
} else {
for (int i = 0; i < values.size(); i++) {
@@ -178,11 +178,11 @@
}
Iterator valueIter = values.iterator();
- Iterator varIter = insert.getVariables().iterator();
+ Iterator<ElementSymbol> varIter = insert.getVariables().iterator();
while(valueIter.hasNext()) {
// Walk through both elements and expressions, which should match up
Expression expression = (Expression) valueIter.next();
- ElementSymbol element = (ElementSymbol) varIter.next();
+ ElementSymbol element = varIter.next();
if (!usingQuery) {
ResolverUtil.setDesiredType(expression, element.getType(), insert);
Added: branches/7.4.x/engine/src/main/java/org/teiid/query/tempdata/AlterTempTable.java
===================================================================
--- branches/7.4.x/engine/src/main/java/org/teiid/query/tempdata/AlterTempTable.java (rev 0)
+++ branches/7.4.x/engine/src/main/java/org/teiid/query/tempdata/AlterTempTable.java 2011-08-01 16:08:41 UTC (rev 3355)
@@ -0,0 +1,78 @@
+package org.teiid.query.tempdata;
+
+import java.util.List;
+
+import org.teiid.query.sql.LanguageVisitor;
+import org.teiid.query.sql.lang.Command;
+import org.teiid.query.sql.symbol.ElementSymbol;
+import org.teiid.query.sql.symbol.SingleElementSymbol;
+
+/*
+ * 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.
+ */
+
+public class AlterTempTable extends Command {
+
+ private String tempTable;
+ private List<ElementSymbol> indexColumns;
+
+ public AlterTempTable(String tempTable) {
+ this.tempTable = tempTable;
+ }
+
+ public String getTempTable() {
+ return tempTable;
+ }
+
+ public List<ElementSymbol> getIndexColumns() {
+ return indexColumns;
+ }
+
+ public void setIndexColumns(List<ElementSymbol> indexColumns) {
+ this.indexColumns = indexColumns;
+ }
+
+ @Override
+ public boolean areResultsCachable() {
+ return false;
+ }
+
+ @Override
+ public Object clone() {
+ return this;
+ }
+
+ @Override
+ public List<SingleElementSymbol> getProjectedSymbols() {
+ return Command.getUpdateCommandSymbol();
+ }
+
+ @Override
+ public int getType() {
+ return Command.TYPE_UNKNOWN;
+ }
+
+ @Override
+ public void acceptVisitor(LanguageVisitor visitor) {
+
+ }
+
+}
Property changes on: branches/7.4.x/engine/src/main/java/org/teiid/query/tempdata/AlterTempTable.java
___________________________________________________________________
Added: svn:mime-type
+ text/plain
Modified: branches/7.4.x/engine/src/main/java/org/teiid/query/tempdata/TempTableDataManager.java
===================================================================
--- branches/7.4.x/engine/src/main/java/org/teiid/query/tempdata/TempTableDataManager.java 2011-07-30 18:54:08 UTC (rev 3354)
+++ branches/7.4.x/engine/src/main/java/org/teiid/query/tempdata/TempTableDataManager.java 2011-08-01 16:08:41 UTC (rev 3355)
@@ -249,6 +249,15 @@
contextStore.removeTempTableByName(tempTableName);
return CollectionTupleSource.createUpdateCountTupleSource(0);
}
+ if (command instanceof AlterTempTable) {
+ AlterTempTable att = (AlterTempTable)command;
+ TempTable tt = contextStore.getOrCreateTempTable(att.getTempTable().toUpperCase(), command, bufferManager, true);
+ tt.setUpdatable(false);
+ if (att.getIndexColumns() != null) {
+ tt.addIndex(att.getIndexColumns(), false);
+ }
+ return CollectionTupleSource.createUpdateCountTupleSource(0);
+ }
return null;
}
Modified: branches/7.4.x/engine/src/test/java/org/teiid/query/processor/xml/TestXMLPlanningEnhancements.java
===================================================================
--- branches/7.4.x/engine/src/test/java/org/teiid/query/processor/xml/TestXMLPlanningEnhancements.java 2011-07-30 18:54:08 UTC (rev 3354)
+++ branches/7.4.x/engine/src/test/java/org/teiid/query/processor/xml/TestXMLPlanningEnhancements.java 2011-08-01 16:08:41 UTC (rev 3355)
@@ -28,6 +28,7 @@
import java.util.List;
import java.util.Map;
+import org.junit.Ignore;
import org.junit.Test;
import org.teiid.client.metadata.ParameterInfo;
import org.teiid.common.buffer.BufferManager;
@@ -309,6 +310,7 @@
TestXMLProcessor.helpTestProcess("SELECT * FROM xmltest.doc18a where supplierID<56", expectedDoc, metadata, dataMgr); //$NON-NLS-1$
}
+ @Ignore("Will plan with a dependent join")
@Test public void testAutoStagingFailsForMappingClassWithProcRelational() throws Exception {
TransformationMetadata metadata = getMetadata("SELECT supplierNum, supplierName, supplierZipCode FROM v1.supplierProc where itemnum = ?"); //$NON-NLS-1$
@@ -386,6 +388,7 @@
/**
* @see #testNested2WithCriteria2
*/
+ @Ignore("Will use a dependent join instead")
@Test public void testAutoStagingFailsByCosting() throws Exception {
TransformationMetadata metadata = TestXMLProcessor.exampleMetadata();
FakeDataManager dataMgr = TestXMLProcessor.exampleDataManagerNested(metadata);
@@ -404,6 +407,7 @@
assertNull(stats.get(ExecStagingTableInstruction.class));
}
+ @Ignore("Will use dependent join instead")
@Test public void testAutoStagingFailsByNoCache() throws Exception {
QueryMetadataInterface metadata = TestXMLProcessor.exampleMetadataCached();
FakeDataManager dataMgr = TestXMLProcessor.exampleDataManagerNested(metadata);
@@ -417,6 +421,7 @@
assertNull(stats.get(ExecStagingTableInstruction.class));
}
+ @Ignore("Will use dependent join")
@Test public void testAutoStagingFailsByNoCacheByGroup() throws Exception {
QueryMetadataInterface metadata = TestXMLProcessor.exampleMetadataCached();
FakeDataManager dataMgr = TestXMLProcessor.exampleDataManagerNested(metadata);
Modified: branches/7.4.x/engine/src/test/java/org/teiid/query/processor/xml/TestXMLProcessor.java
===================================================================
--- branches/7.4.x/engine/src/test/java/org/teiid/query/processor/xml/TestXMLProcessor.java 2011-07-30 18:54:08 UTC (rev 3354)
+++ branches/7.4.x/engine/src/test/java/org/teiid/query/processor/xml/TestXMLProcessor.java 2011-08-01 16:08:41 UTC (rev 3355)
@@ -8866,33 +8866,6 @@
helpTestProcess("SELECT * FROM xmltest.doc1 WHERE NOT (ItemID IN (SELECT itemNum FROM stock.items WHERE itemNum = '001') )", expectedDoc, metadata, dataMgr); //$NON-NLS-1$
}
- public void XXXtestSubqueryInXMLQueryCriteria4() throws Exception {
- QueryMetadataInterface metadata = exampleMetadataCached();
- FakeDataManager dataMgr = exampleDataManager(metadata);
- String expectedDoc =
- "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n" + //$NON-NLS-1$
- "<Catalogs xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">\r\n" + //$NON-NLS-1$
- " <Catalog>\r\n" + //$NON-NLS-1$
- " <Items>\r\n" + //$NON-NLS-1$
- " <Item ItemID=\"001\">\r\n" + //$NON-NLS-1$
- " <Name>Lamp</Name>\r\n" + //$NON-NLS-1$
- " <Quantity>5</Quantity>\r\n" + //$NON-NLS-1$
- " </Item>\r\n" + //$NON-NLS-1$
- " <Item ItemID=\"002\">\r\n" + //$NON-NLS-1$
- " <Name>Screwdriver</Name>\r\n" + //$NON-NLS-1$
- " <Quantity>100</Quantity>\r\n" + //$NON-NLS-1$
- " </Item>\r\n" + //$NON-NLS-1$
- " <Item ItemID=\"003\">\r\n" + //$NON-NLS-1$
- " <Name>Goat</Name>\r\n" + //$NON-NLS-1$
- " <Quantity>4</Quantity>\r\n" + //$NON-NLS-1$
- " </Item>\r\n" + //$NON-NLS-1$
- " </Items>\r\n" + //$NON-NLS-1$
- " </Catalog>\r\n" + //$NON-NLS-1$
- "</Catalogs>\r\n\r\n"; //$NON-NLS-1$
-
- helpTestProcess("SELECT * FROM xmltest.doc1 WHERE EXISTS (SELECT itemNum FROM stock.items WHERE itemNum = '001')", expectedDoc, metadata, dataMgr); //$NON-NLS-1$
- }
-
@Test public void testSubqueryInXMLQueryCriteriaNestedSubquery() throws Exception {
QueryMetadataInterface metadata = exampleMetadataCached();
FakeDataManager dataMgr = exampleDataManager(metadata);
14 years, 8 months