DNA SVN: r1286 - in trunk: dna-graph/src/main/java/org/jboss/dna/graph and 14 other directories.
by dna-commits@lists.jboss.org
Author: rhauch
Date: 2009-10-03 00:09:29 -0400 (Sat, 03 Oct 2009)
New Revision: 1286
Added:
trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/model/NodeDepth.java
trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/model/NodePath.java
trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/parse/InvalidQueryException.java
trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/xpath/XPathQueryParser.java
trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/xpath/XPathToQueryTranslator.java
trunk/dna-jcr/src/test/java/org/jboss/dna/jcr/xpath/XPathToQueryTranslatorTest.java
Removed:
trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/InvalidQueryException.java
Modified:
trunk/.gitignore
trunk/dna-graph/src/main/java/org/jboss/dna/graph/GraphI18n.java
trunk/dna-graph/src/main/java/org/jboss/dna/graph/property/DateTime.java
trunk/dna-graph/src/main/java/org/jboss/dna/graph/property/basic/JodaDateTime.java
trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/QueryBuilder.java
trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/QueryEngine.java
trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/model/AllNodes.java
trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/model/Literal.java
trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/model/NamedSelector.java
trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/model/Operator.java
trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/model/Visitor.java
trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/model/Visitors.java
trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/optimize/RewriteIdentityJoins.java
trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/parse/QueryParser.java
trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/parse/SqlQueryParser.java
trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/process/ProcessingComponent.java
trunk/dna-graph/src/main/resources/org/jboss/dna/graph/GraphI18n.properties
trunk/dna-graph/src/test/java/org/jboss/dna/graph/query/QueryBuilderTest.java
trunk/dna-graph/src/test/java/org/jboss/dna/graph/query/parse/SqlQueryParserTest.java
trunk/dna-graph/src/test/java/org/jboss/dna/graph/query/process/AbstractQueryResultsTest.java
trunk/dna-graph/src/test/java/org/jboss/dna/graph/query/process/SortValuesComponentTest.java
trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/xpath/XPath.java
trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/xpath/XPathParser.java
trunk/dna-jcr/src/test/java/org/jboss/dna/jcr/xpath/XPathParserTest.java
trunk/dna-search/src/main/java/org/jboss/dna/search/LuceneQueryEngine.java
Log:
DNA-467 Add search/query support to the graph API
DNA-468 Add XPath query language support
Added a lot more implementation and unit tests behind the XPath parser, the XPath AST objects, and the translator that converts an XPath AST into a SQL query model. Found and fixed a number of issues in several of the 'dna-graph' classes, including some tweaks to the SQL query odel, the SQL parser, minor improvements to the JodaDateTime class, and some changes to the exception handling in the 'dna-graph' query model and builder.
At this point, the XPath support is pretty good, though still not complete. It may be good enough to use for a while - until we have more examples. The unit tests are verifying not only that the XPath expressions can be parsed, but that they're also converted correctly to an expected SQL representation.
The XPath functionality has not yet been integrated into the JCR implementation, since that requires hooking up the LuceneQueryEngine (which still needs some work). However, I plan to start putting more of the pieces together and focusing on wrapping up the LuceneQueryEngine.
Modified: trunk/.gitignore
===================================================================
--- trunk/.gitignore 2009-10-03 04:07:41 UTC (rev 1285)
+++ trunk/.gitignore 2009-10-03 04:09:29 UTC (rev 1286)
@@ -39,6 +39,7 @@
/web/dna-web-jcr-rest/target/
/web/dna-web-jcr-rest-war/target/
+/web/dna-web-jcr-rest-client/target/
/extensions/dna-classloader-maven/target
/extensions/dna-common-jdbc/target
Modified: trunk/dna-graph/src/main/java/org/jboss/dna/graph/GraphI18n.java
===================================================================
--- trunk/dna-graph/src/main/java/org/jboss/dna/graph/GraphI18n.java 2009-10-03 04:07:41 UTC (rev 1285)
+++ trunk/dna-graph/src/main/java/org/jboss/dna/graph/GraphI18n.java 2009-10-03 04:09:29 UTC (rev 1286)
@@ -128,6 +128,7 @@
public static I18n childNotFound;
/* Query */
+ public static I18n unknownQueryLanguage;
public static I18n tableDoesNotExist;
public static I18n columnDoesNotExistOnTable;
public static I18n columnDoesNotExistInQuery;
Modified: trunk/dna-graph/src/main/java/org/jboss/dna/graph/property/DateTime.java
===================================================================
--- trunk/dna-graph/src/main/java/org/jboss/dna/graph/property/DateTime.java 2009-10-03 04:07:41 UTC (rev 1285)
+++ trunk/dna-graph/src/main/java/org/jboss/dna/graph/property/DateTime.java 2009-10-03 04:09:29 UTC (rev 1286)
@@ -71,6 +71,14 @@
long getMilliseconds();
/**
+ * Get the number of milliseconds from 1970-01-01T00:00Z with this time converted to UTC. This value is consistent with the
+ * JDK {@link java.util.Date Date} and {@link java.util.Calendar Calendar} classes.
+ *
+ * @return the number of milliseconds from 1970-01-01T00:00Z in the UTC time zone
+ */
+ long getMillisecondsInUtc();
+
+ /**
* Get this instance represented as a standard JDK {@link java.util.Date} instance. Note that this conversion loses the time
* zone information, as the standard JDK {@link java.util.Date} does not represent time zones.
*
Modified: trunk/dna-graph/src/main/java/org/jboss/dna/graph/property/basic/JodaDateTime.java
===================================================================
--- trunk/dna-graph/src/main/java/org/jboss/dna/graph/property/basic/JodaDateTime.java 2009-10-03 04:07:41 UTC (rev 1285)
+++ trunk/dna-graph/src/main/java/org/jboss/dna/graph/property/basic/JodaDateTime.java 2009-10-03 04:09:29 UTC (rev 1286)
@@ -40,6 +40,8 @@
@Immutable
public class JodaDateTime implements org.jboss.dna.graph.property.DateTime {
+ private static final DateTimeZone UTC_ZONE = DateTimeZone.forID("UTC");
+
/**
*/
private static final long serialVersionUID = -730188225988292422L;
@@ -47,36 +49,44 @@
private static final int MILLIS_IN_HOUR = 1000 * 60 * 60;
private final DateTime instance;
+ private final long millisInUtc;
public JodaDateTime() {
this.instance = new DateTime();
+ this.millisInUtc = instance.withZone(UTC_ZONE).getMillis();
}
public JodaDateTime( String iso8601 ) {
this.instance = new DateTime(iso8601);
+ this.millisInUtc = instance.withZone(UTC_ZONE).getMillis();
}
public JodaDateTime( String iso8601,
String timeZoneId ) {
this.instance = new DateTime(iso8601, DateTimeZone.forID(timeZoneId));
+ this.millisInUtc = instance.withZone(UTC_ZONE).getMillis();
}
public JodaDateTime( long milliseconds ) {
this.instance = new DateTime(milliseconds);
+ this.millisInUtc = instance.withZone(UTC_ZONE).getMillis();
}
public JodaDateTime( long milliseconds,
Chronology chronology ) {
this.instance = new DateTime(milliseconds, chronology);
+ this.millisInUtc = instance.withZone(UTC_ZONE).getMillis();
}
public JodaDateTime( long milliseconds,
String timeZoneId ) {
this.instance = new DateTime(milliseconds, DateTimeZone.forID(timeZoneId));
+ this.millisInUtc = instance.withZone(UTC_ZONE).getMillis();
}
public JodaDateTime( DateTimeZone dateTimeZone ) {
this.instance = new DateTime(dateTimeZone);
+ this.millisInUtc = instance.withZone(UTC_ZONE).getMillis();
}
public JodaDateTime( int year,
@@ -87,6 +97,7 @@
int secondOfMinute,
int millisecondsOfSecond ) {
this.instance = new DateTime(year, monthOfYear, dayOfMonth, hourOfDay, minuteOfHour, secondOfMinute, millisecondsOfSecond);
+ this.millisInUtc = instance.withZone(UTC_ZONE).getMillis();
}
public JodaDateTime( int year,
@@ -99,6 +110,7 @@
Chronology chronology ) {
this.instance = new DateTime(year, monthOfYear, dayOfMonth, hourOfDay, minuteOfHour, secondOfMinute,
millisecondsOfSecond, chronology);
+ this.millisInUtc = instance.withZone(UTC_ZONE).getMillis();
}
public JodaDateTime( int year,
@@ -111,6 +123,7 @@
DateTimeZone dateTimeZone ) {
this.instance = new DateTime(year, monthOfYear, dayOfMonth, hourOfDay, minuteOfHour, secondOfMinute,
millisecondsOfSecond, dateTimeZone);
+ this.millisInUtc = instance.withZone(UTC_ZONE).getMillis();
}
public JodaDateTime( int year,
@@ -123,6 +136,7 @@
int timeZoneOffsetHours ) {
this.instance = new DateTime(year, monthOfYear, dayOfMonth, hourOfDay, minuteOfHour, secondOfMinute,
millisecondsOfSecond, DateTimeZone.forOffsetHours(timeZoneOffsetHours));
+ this.millisInUtc = instance.withZone(UTC_ZONE).getMillis();
}
public JodaDateTime( int year,
@@ -135,18 +149,22 @@
String timeZoneId ) {
this.instance = new DateTime(year, monthOfYear, dayOfMonth, hourOfDay, minuteOfHour, secondOfMinute,
millisecondsOfSecond, DateTimeZone.forID(timeZoneId));
+ this.millisInUtc = instance.withZone(UTC_ZONE).getMillis();
}
public JodaDateTime( java.util.Date jdkDate ) {
this.instance = new DateTime(jdkDate);
+ this.millisInUtc = instance.withZone(UTC_ZONE).getMillis();
}
public JodaDateTime( java.util.Calendar jdkCalendar ) {
this.instance = new DateTime(jdkCalendar);
+ this.millisInUtc = instance.withZone(UTC_ZONE).getMillis();
}
public JodaDateTime( DateTime dateTime ) {
this.instance = dateTime; // it's immutable, so just hold onto the supplied instance
+ this.millisInUtc = instance.withZone(UTC_ZONE).getMillis();
}
/**
@@ -207,7 +225,16 @@
/**
* {@inheritDoc}
+ *
+ * @see org.jboss.dna.graph.property.DateTime#getMillisecondsInUtc()
*/
+ public long getMillisecondsInUtc() {
+ return millisInUtc;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
public int getMinuteOfHour() {
return this.instance.getMinuteOfHour();
}
@@ -315,12 +342,8 @@
* {@inheritDoc}
*/
public int compareTo( org.jboss.dna.graph.property.DateTime that ) {
- if (that instanceof JodaDateTime) {
- return this.instance.compareTo(((JodaDateTime)that).instance);
- }
- if (that == null) return 1;
- long diff = this.toUtcTimeZone().getMilliseconds() - that.toUtcTimeZone().getMilliseconds();
- return (int)diff;
+ long diff = this.getMillisecondsInUtc() - that.getMillisecondsInUtc();
+ return diff == 0 ? 0 : diff > 0 ? 1 : -1;
}
/**
@@ -328,7 +351,7 @@
*/
@Override
public int hashCode() {
- return this.instance.hashCode();
+ return (int)this.millisInUtc;
}
/**
@@ -337,18 +360,13 @@
@Override
public boolean equals( Object obj ) {
if (obj == this) return true;
- if (obj instanceof JodaDateTime) {
- JodaDateTime that = (JodaDateTime)obj;
-
- /*
- * The equals semantics for JodaDateTimes are very strict, implying that not only are the two instants represented
- * by the JodaDateTimes logically equivalent, but also that the Chronology and DateTimeZone are the same.
- * Instead, use isEqual, which only checks that the two JodaDateTimes are logically equivalent.
- */
- return this.instance.isEqual(that.instance);
+ if (obj instanceof org.jboss.dna.graph.property.DateTime) {
+ org.jboss.dna.graph.property.DateTime that = (org.jboss.dna.graph.property.DateTime)obj;
+ return this.getMillisecondsInUtc() == that.getMillisecondsInUtc();
}
if (obj instanceof DateTime) {
- return this.instance.equals(obj);
+ DateTime that = (DateTime)obj;
+ return this.getMillisecondsInUtc() == that.withZone(UTC_ZONE).getMillis();
}
return false;
}
@@ -365,7 +383,9 @@
* {@inheritDoc}
*/
public org.jboss.dna.graph.property.DateTime toUtcTimeZone() {
- DateTime jodaTime = this.instance.withZone(DateTimeZone.forID("UTC"));
+ DateTimeZone utc = DateTimeZone.forID("UTC");
+ if (this.instance.getZone().equals(utc)) return this;
+ DateTime jodaTime = this.instance.withZone(utc);
return new JodaDateTime(jodaTime);
}
Deleted: trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/InvalidQueryException.java
===================================================================
--- trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/InvalidQueryException.java 2009-10-03 04:07:41 UTC (rev 1285)
+++ trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/InvalidQueryException.java 2009-10-03 04:09:29 UTC (rev 1286)
@@ -1,65 +0,0 @@
-/*
- * JBoss DNA (http://www.jboss.org/dna)
- * 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.
- * See the AUTHORS.txt file in the distribution for a full listing of
- * individual contributors.
- *
- * JBoss DNA is free software. Unless otherwise indicated, all code in JBoss DNA
- * is licensed to you 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.
- *
- * JBoss DNA 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 software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- */
-package org.jboss.dna.graph.query;
-
-/**
- *
- */
-public class InvalidQueryException extends RuntimeException {
-
- private static final long serialVersionUID = 1L;
-
- /**
- *
- */
- public InvalidQueryException() {
- }
-
- /**
- * @param message
- */
- public InvalidQueryException( String message ) {
- super(message);
-
- }
-
- /**
- * @param cause
- */
- public InvalidQueryException( Throwable cause ) {
- super(cause);
-
- }
-
- /**
- * @param message
- * @param cause
- */
- public InvalidQueryException( String message,
- Throwable cause ) {
- super(message, cause);
-
- }
-
-}
Modified: trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/QueryBuilder.java
===================================================================
--- trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/QueryBuilder.java 2009-10-03 04:07:41 UTC (rev 1285)
+++ trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/QueryBuilder.java 2009-10-03 04:09:29 UTC (rev 1286)
@@ -23,20 +23,28 @@
*/
package org.jboss.dna.graph.query;
+import java.math.BigDecimal;
+import java.net.URI;
import java.util.LinkedList;
import java.util.List;
+import java.util.UUID;
import java.util.concurrent.atomic.AtomicBoolean;
import net.jcip.annotations.NotThreadSafe;
import org.jboss.dna.common.util.CheckArg;
import org.jboss.dna.graph.ExecutionContext;
import org.jboss.dna.graph.GraphI18n;
+import org.jboss.dna.graph.property.Binary;
+import org.jboss.dna.graph.property.DateTime;
import org.jboss.dna.graph.property.Name;
import org.jboss.dna.graph.property.Path;
+import org.jboss.dna.graph.property.PropertyType;
+import org.jboss.dna.graph.property.ValueFactories;
import org.jboss.dna.graph.property.ValueFormatException;
import org.jboss.dna.graph.query.model.AllNodes;
import org.jboss.dna.graph.query.model.And;
import org.jboss.dna.graph.query.model.BindVariableName;
import org.jboss.dna.graph.query.model.ChildNode;
+import org.jboss.dna.graph.query.model.ChildNodeJoinCondition;
import org.jboss.dna.graph.query.model.Column;
import org.jboss.dna.graph.query.model.Comparison;
import org.jboss.dna.graph.query.model.Constraint;
@@ -54,8 +62,10 @@
import org.jboss.dna.graph.query.model.Literal;
import org.jboss.dna.graph.query.model.LowerCase;
import org.jboss.dna.graph.query.model.NamedSelector;
+import org.jboss.dna.graph.query.model.NodeDepth;
import org.jboss.dna.graph.query.model.NodeLocalName;
import org.jboss.dna.graph.query.model.NodeName;
+import org.jboss.dna.graph.query.model.NodePath;
import org.jboss.dna.graph.query.model.Not;
import org.jboss.dna.graph.query.model.Operator;
import org.jboss.dna.graph.query.model.Or;
@@ -302,13 +312,13 @@
*
* @param name the name; may not be null
* @return the name; never null
- * @throws InvalidQueryException if the supplied name is not a valid {@link Name} object
+ * @throws IllegalArgumentException if the supplied name is not a valid {@link Name} object
*/
protected Name name( String name ) {
try {
return context.getValueFactories().getNameFactory().create(name.trim());
} catch (ValueFormatException e) {
- throw new InvalidQueryException(GraphI18n.expectingValidName.text(name));
+ throw new IllegalArgumentException(GraphI18n.expectingValidName.text(name));
}
}
@@ -318,13 +328,13 @@
*
* @param path the path; may not be null
* @return the path; never null
- * @throws InvalidQueryException if the supplied string is not a valid {@link Path} object
+ * @throws IllegalArgumentException if the supplied string is not a valid {@link Path} object
*/
protected Path path( String path ) {
try {
return context.getValueFactories().getPathFactory().create(path.trim());
} catch (ValueFormatException e) {
- throw new InvalidQueryException(GraphI18n.expectingValidPath.text(path));
+ throw new IllegalArgumentException(GraphI18n.expectingValidPath.text(path));
}
}
@@ -335,7 +345,7 @@
*
* @param nameExpression the expression specifying the columm name and (optionally) the table's name or alias; may not be null
* @return the column; never null
- * @throws InvalidQueryException if the table's name/alias is not specified, but the query has more than one named source
+ * @throws IllegalArgumentException if the table's name/alias is not specified, but the query has more than one named source
*/
protected Column column( String nameExpression ) {
String[] parts = nameExpression.split("(?<!\\\\)\\."); // a . not preceded by an escaping slash
@@ -356,7 +366,7 @@
propertyName = name(parts[0]);
columnName = parts[0];
} else {
- throw new InvalidQueryException(GraphI18n.columnMustBeScoped.text(parts[0]));
+ throw new IllegalArgumentException(GraphI18n.columnMustBeScoped.text(parts[0]));
}
}
return new Column(name, propertyName, columnName);
@@ -373,16 +383,15 @@
}
/**
- * Select the columns with the supplied names. Each column name has the form "<code>[tableName.]columnName</code>", where "
- * <code>tableName</code>" must be a valid table name or alias. If the table name/alias is not specified, then there is
- * expected to be a single FROM clause with a single named selector.
+ * Add to the select clause the columns with the supplied names. Each column name has the form "
+ * <code>[tableName.]columnName</code>", where " <code>tableName</code>" must be a valid table name or alias. If the table
+ * name/alias is not specified, then there is expected to be a single FROM clause with a single named selector.
*
* @param columnNames the column expressions; may not be null
* @return this builder object, for convenience in method chaining
- * @throws InvalidQueryException if the table's name/alias is not specified, but the query has more than one named source
+ * @throws IllegalArgumentException if the table's name/alias is not specified, but the query has more than one named source
*/
public QueryBuilder select( String... columnNames ) {
- columns.clear();
for (String expression : columnNames) {
columns.add(column(expression));
}
@@ -406,7 +415,7 @@
*
* @param columnNames the column expressions; may not be null
* @return this builder object, for convenience in method chaining
- * @throws InvalidQueryException if the table's name/alias is not specified, but the query has more than one named source
+ * @throws IllegalArgumentException if the table's name/alias is not specified, but the query has more than one named source
*/
public QueryBuilder selectDistinct( String... columnNames ) {
distinct = true;
@@ -549,6 +558,73 @@
}
/**
+ * Perform an inner join between the already defined source with the "__ALLNODES__" table using the supplied alias.
+ *
+ * @param alias the alias for the "__ALL_NODES" table; may not be null
+ * @return the component that must be used to complete the join specification; never null
+ */
+ public JoinClause joinAllNodesAs( String alias ) {
+ return innerJoinAllNodesAs(alias);
+ }
+
+ /**
+ * Perform an inner join between the already defined source with the "__ALL_NODES" table using the supplied alias.
+ *
+ * @param alias the alias for the "__ALL_NODES" table; may not be null
+ * @return the component that must be used to complete the join specification; never null
+ */
+ public JoinClause innerJoinAllNodesAs( String alias ) {
+ // Expect there to be a source already ...
+ return new JoinClause(namedSelector(AllNodes.ALL_NODES_NAME + " AS " + alias), JoinType.INNER);
+ }
+
+ /**
+ * Perform a cross join between the already defined source with the "__ALL_NODES" table using the supplied alias. Cross joins
+ * have a higher precedent than other join types, so if this is called after another join was defined, the resulting cross
+ * join will be between the previous join's right-hand side and the supplied table.
+ *
+ * @param alias the alias for the "__ALL_NODES" table; may not be null
+ * @return the component that must be used to complete the join specification; never null
+ */
+ public JoinClause crossJoinAllNodesAs( String alias ) {
+ // Expect there to be a source already ...
+ return new JoinClause(namedSelector(AllNodes.ALL_NODES_NAME + " AS " + alias), JoinType.CROSS);
+ }
+
+ /**
+ * Perform a full outer join between the already defined source with the "__ALL_NODES" table using the supplied alias.
+ *
+ * @param alias the alias for the "__ALL_NODES" table; may not be null
+ * @return the component that must be used to complete the join specification; never null
+ */
+ public JoinClause fullOuterJoinAllNodesAs( String alias ) {
+ // Expect there to be a source already ...
+ return new JoinClause(namedSelector(AllNodes.ALL_NODES_NAME + " AS " + alias), JoinType.FULL_OUTER);
+ }
+
+ /**
+ * Perform a left outer join between the already defined source with the "__ALL_NODES" table using the supplied alias.
+ *
+ * @param alias the alias for the "__ALL_NODES" table; may not be null
+ * @return the component that must be used to complete the join specification; never null
+ */
+ public JoinClause leftOuterJoinAllNodesAs( String alias ) {
+ // Expect there to be a source already ...
+ return new JoinClause(namedSelector(AllNodes.ALL_NODES_NAME + " AS " + alias), JoinType.LEFT_OUTER);
+ }
+
+ /**
+ * Perform a right outer join between the already defined source with the "__ALL_NODES" table using the supplied alias.
+ *
+ * @param alias the alias for the "__ALL_NODES" table; may not be null
+ * @return the component that must be used to complete the join specification; never null
+ */
+ public JoinClause rightOuterJoinAllNodesAs( String alias ) {
+ // Expect there to be a source already ...
+ return new JoinClause(namedSelector(AllNodes.ALL_NODES_NAME + " AS " + alias), JoinType.RIGHT_OUTER);
+ }
+
+ /**
* Specify the maximum number of rows that are to be returned in the results. By default there is no limit.
*
* @param rowLimit the maximum number of rows
@@ -703,7 +779,7 @@
*
* @param tableName the table name
* @return the selector name matching the supplied table name; never null
- * @throws InvalidQueryException if the table name could not be resolved
+ * @throws IllegalArgumentException if the table name could not be resolved
*/
protected SelectorName nameOf( String tableName ) {
final SelectorName name = new SelectorName(tableName);
@@ -723,7 +799,7 @@
}
});
if (notFound.get()) {
- throw new InvalidQueryException("Expected \"" + tableName + "\" to be a valid table name or alias");
+ throw new IllegalArgumentException("Expected \"" + tableName + "\" to be a valid table name or alias");
}
return name;
}
@@ -734,12 +810,13 @@
*
* @param columnEqualExpression the equality expression between the two tables; may not be null
* @return the query builder instance, for method chaining purposes
+ * @throws IllegalArgumentException if the supplied expression is not an equality expression
*/
public QueryBuilder on( String columnEqualExpression ) {
String[] parts = columnEqualExpression.split("=");
if (parts.length != 2) {
- throw new InvalidQueryException("Expected equality expression for columns, but found \"" + columnEqualExpression
- + "\"");
+ throw new IllegalArgumentException("Expected equality expression for columns, but found \""
+ + columnEqualExpression + "\"");
}
return createJoin(new EquiJoinCondition(column(parts[0]), column(parts[1])));
}
@@ -780,7 +857,7 @@
*/
public QueryBuilder onChildNode( String parentTable,
String childTable ) {
- return createJoin(new DescendantNodeJoinCondition(nameOf(parentTable), nameOf(childTable)));
+ return createJoin(new ChildNodeJoinCondition(nameOf(parentTable), nameOf(childTable)));
}
protected QueryBuilder createJoin( JoinCondition condition ) {
@@ -836,16 +913,34 @@
public ComparisonBuilder fullTextSearchScore( String table );
/**
- * Constrains the nodes in the the supplied table such that they must have a matching node local name.
+ * Constrains the nodes in the the supplied table based upon criteria on the node's depth.
*
* @param table the name of the table; may not be null and must refer to a valid name or alias of a table appearing in the
* FROM clause
* @return the interface for completing the value portion of the criteria specification; never null
*/
+ public ComparisonBuilder depth( String table );
+
+ /**
+ * Constrains the nodes in the the supplied table based upon criteria on the node's path.
+ *
+ * @param table the name of the table; may not be null and must refer to a valid name or alias of a table appearing in the
+ * FROM clause
+ * @return the interface for completing the value portion of the criteria specification; never null
+ */
+ public ComparisonBuilder path( String table );
+
+ /**
+ * Constrains the nodes in the the supplied table based upon criteria on the node's local name.
+ *
+ * @param table the name of the table; may not be null and must refer to a valid name or alias of a table appearing in the
+ * FROM clause
+ * @return the interface for completing the value portion of the criteria specification; never null
+ */
public ComparisonBuilder nodeLocalName( String table );
/**
- * Constrains the nodes in the the supplied table such that they must have a matching node name.
+ * Constrains the nodes in the the supplied table based upon criteria on the node's name.
*
* @param table the name of the table; may not be null and must refer to a valid name or alias of a table appearing in the
* FROM clause
@@ -987,8 +1082,7 @@
*/
public ConstraintBuilder isSameNode( String table,
String asNodeAtPath ) {
- if (constraint != null) throw new InvalidQueryException("Existing constraint; call in proper order");
- return setConstraint(new SameNode(selector(table), path(asNodeAtPath)));
+ return setConstraint(new SameNode(selector(table), QueryBuilder.this.path(asNodeAtPath)));
}
/**
@@ -1001,8 +1095,7 @@
*/
public ConstraintBuilder isChild( String childTable,
String parentPath ) {
- if (constraint != null) throw new InvalidQueryException("Existing constraint; call in proper order");
- return setConstraint(new ChildNode(selector(childTable), path(parentPath)));
+ return setConstraint(new ChildNode(selector(childTable), QueryBuilder.this.path(parentPath)));
}
/**
@@ -1015,12 +1108,11 @@
*/
public ConstraintBuilder isBelowPath( String descendantTable,
String ancestorPath ) {
- if (constraint != null) throw new InvalidQueryException("Existing constraint; call in proper order");
- return setConstraint(new DescendantNode(selector(descendantTable), path(ancestorPath)));
+ return setConstraint(new DescendantNode(selector(descendantTable), QueryBuilder.this.path(ancestorPath)));
}
/**
- * Define a constraint clause that the node within the named table has at least one value for the named property. path.
+ * Define a constraint clause that the node within the named table has at least one value for the named property.
*
* @param table the name of the table; may not be null and must refer to a valid name or alias of a table appearing in the
* FROM clause
@@ -1029,7 +1121,6 @@
*/
public ConstraintBuilder hasProperty( String table,
String propertyName ) {
- if (constraint != null) throw new InvalidQueryException("Existing constraint; call in proper order");
return setConstraint(new PropertyExistence(selector(table), name(propertyName)));
}
@@ -1044,7 +1135,6 @@
*/
public ConstraintBuilder search( String table,
String searchExpression ) {
- if (constraint != null) throw new InvalidQueryException("Existing constraint; call in proper order");
return setConstraint(new FullTextSearch(selector(table), searchExpression));
}
@@ -1061,7 +1151,6 @@
public ConstraintBuilder search( String table,
String propertyName,
String searchExpression ) {
- if (constraint != null) throw new InvalidQueryException("Existing constraint; call in proper order");
return setConstraint(new FullTextSearch(selector(table), name(propertyName), searchExpression));
}
@@ -1097,6 +1186,24 @@
/**
* {@inheritDoc}
*
+ * @see org.jboss.dna.graph.query.QueryBuilder.DynamicOperandBuilder#depth(java.lang.String)
+ */
+ public ComparisonBuilder depth( String table ) {
+ return new ComparisonBuilder(this, new NodeDepth(selector(table)));
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.jboss.dna.graph.query.QueryBuilder.DynamicOperandBuilder#path(java.lang.String)
+ */
+ public ComparisonBuilder path( String table ) {
+ return new ComparisonBuilder(this, new NodePath(selector(table)));
+ }
+
+ /**
+ * {@inheritDoc}
+ *
* @see org.jboss.dna.graph.query.QueryBuilder.DynamicOperandBuilder#nodeLocalName(String)
*/
public ComparisonBuilder nodeLocalName( String table ) {
@@ -1179,6 +1286,400 @@
}
}
+ public class CastAs {
+ private final RightHandSide rhs;
+ private final Object value;
+
+ protected CastAs( RightHandSide rhs,
+ Object value ) {
+ this.rhs = rhs;
+ this.value = value;
+ }
+
+ private ValueFactories factories() {
+ return QueryBuilder.this.context.getValueFactories();
+ }
+
+ /**
+ * Define the right-hand side literal value cast as the specified type.
+ *
+ * @param type the property type; may not be null
+ * @return the constraint builder; never null
+ */
+ public ConstraintBuilder as( PropertyType type ) {
+ return rhs.comparisonBuilder.is(rhs.operator, factories().getValueFactory(type).create(value));
+ }
+
+ /**
+ * Define the right-hand side literal value cast as a {@link PropertyType#STRING}.
+ *
+ * @return the constraint builder; never null
+ */
+ public ConstraintBuilder asString() {
+ return as(PropertyType.STRING);
+ }
+
+ /**
+ * Define the right-hand side literal value cast as a {@link PropertyType#BOOLEAN}.
+ *
+ * @return the constraint builder; never null
+ */
+ public ConstraintBuilder asBoolean() {
+ return as(PropertyType.BOOLEAN);
+ }
+
+ /**
+ * Define the right-hand side literal value cast as a {@link PropertyType#LONG}.
+ *
+ * @return the constraint builder; never null
+ */
+ public ConstraintBuilder asLong() {
+ return as(PropertyType.LONG);
+ }
+
+ /**
+ * Define the right-hand side literal value cast as a {@link PropertyType#DOUBLE}.
+ *
+ * @return the constraint builder; never null
+ */
+ public ConstraintBuilder asDouble() {
+ return as(PropertyType.DOUBLE);
+ }
+
+ /**
+ * Define the right-hand side literal value cast as a {@link PropertyType#DECIMAL}.
+ *
+ * @return the constraint builder; never null
+ */
+ public ConstraintBuilder asDecimal() {
+ return as(PropertyType.DECIMAL);
+ }
+
+ /**
+ * Define the right-hand side literal value cast as a {@link PropertyType#DATE}.
+ *
+ * @return the constraint builder; never null
+ */
+ public ConstraintBuilder asDate() {
+ return as(PropertyType.DATE);
+ }
+
+ /**
+ * Define the right-hand side literal value cast as a {@link PropertyType#NAME}.
+ *
+ * @return the constraint builder; never null
+ */
+ public ConstraintBuilder asName() {
+ return as(PropertyType.NAME);
+ }
+
+ /**
+ * Define the right-hand side literal value cast as a {@link PropertyType#PATH}.
+ *
+ * @return the constraint builder; never null
+ */
+ public ConstraintBuilder asPath() {
+ return as(PropertyType.PATH);
+ }
+
+ /**
+ * Define the right-hand side literal value cast as a {@link PropertyType#BINARY}.
+ *
+ * @return the constraint builder; never null
+ */
+ public ConstraintBuilder asBinary() {
+ return as(PropertyType.BINARY);
+ }
+
+ /**
+ * Define the right-hand side literal value cast as a {@link PropertyType#REFERENCE}.
+ *
+ * @return the constraint builder; never null
+ */
+ public ConstraintBuilder asReference() {
+ return as(PropertyType.REFERENCE);
+ }
+
+ /**
+ * Define the right-hand side literal value cast as a {@link PropertyType#URI}.
+ *
+ * @return the constraint builder; never null
+ */
+ public ConstraintBuilder asUri() {
+ return as(PropertyType.URI);
+ }
+
+ /**
+ * Define the right-hand side literal value cast as a {@link PropertyType#UUID}.
+ *
+ * @return the constraint builder; never null
+ */
+ public ConstraintBuilder asUuid() {
+ return as(PropertyType.UUID);
+ }
+ }
+
+ public class RightHandSide {
+ protected final Operator operator;
+ protected final ComparisonBuilder comparisonBuilder;
+
+ protected RightHandSide( ComparisonBuilder comparisonBuilder,
+ Operator operator ) {
+ this.operator = operator;
+ this.comparisonBuilder = comparisonBuilder;
+ }
+
+ /**
+ * Define the right-hand side of a comparison.
+ *
+ * @param literal the literal value;
+ * @return the constraint builder; never null
+ */
+ public ConstraintBuilder literal( String literal ) {
+ return comparisonBuilder.is(operator, literal);
+ }
+
+ /**
+ * Define the right-hand side of a comparison.
+ *
+ * @param literal the literal value;
+ * @return the constraint builder; never null
+ */
+ public ConstraintBuilder literal( int literal ) {
+ return comparisonBuilder.is(operator, literal);
+ }
+
+ /**
+ * Define the right-hand side of a comparison.
+ *
+ * @param literal the literal value;
+ * @return the constraint builder; never null
+ */
+ public ConstraintBuilder literal( long literal ) {
+ return comparisonBuilder.is(operator, literal);
+ }
+
+ /**
+ * Define the right-hand side of a comparison.
+ *
+ * @param literal the literal value;
+ * @return the constraint builder; never null
+ */
+ public ConstraintBuilder literal( float literal ) {
+ return comparisonBuilder.is(operator, literal);
+ }
+
+ /**
+ * Define the right-hand side of a comparison.
+ *
+ * @param literal the literal value;
+ * @return the constraint builder; never null
+ */
+ public ConstraintBuilder literal( double literal ) {
+ return comparisonBuilder.is(operator, literal);
+ }
+
+ /**
+ * Define the right-hand side of a comparison.
+ *
+ * @param literal the literal value;
+ * @return the constraint builder; never null
+ */
+ public ConstraintBuilder literal( DateTime literal ) {
+ return comparisonBuilder.is(operator, literal.toUtcTimeZone());
+ }
+
+ /**
+ * Define the right-hand side of a comparison.
+ *
+ * @param literal the literal value;
+ * @return the constraint builder; never null
+ */
+ public ConstraintBuilder literal( Path literal ) {
+ return comparisonBuilder.is(operator, literal);
+ }
+
+ /**
+ * Define the right-hand side of a comparison.
+ *
+ * @param literal the literal value;
+ * @return the constraint builder; never null
+ */
+ public ConstraintBuilder literal( Name literal ) {
+ return comparisonBuilder.is(operator, literal);
+ }
+
+ /**
+ * Define the right-hand side of a comparison.
+ *
+ * @param literal the literal value;
+ * @return the constraint builder; never null
+ */
+ public ConstraintBuilder literal( URI literal ) {
+ return comparisonBuilder.is(operator, literal);
+ }
+
+ /**
+ * Define the right-hand side of a comparison.
+ *
+ * @param literal the literal value;
+ * @return the constraint builder; never null
+ */
+ public ConstraintBuilder literal( UUID literal ) {
+ return comparisonBuilder.is(operator, literal);
+ }
+
+ /**
+ * Define the right-hand side of a comparison.
+ *
+ * @param literal the literal value;
+ * @return the constraint builder; never null
+ */
+ public ConstraintBuilder literal( Binary literal ) {
+ return comparisonBuilder.is(operator, literal);
+ }
+
+ /**
+ * Define the right-hand side of a comparison.
+ *
+ * @param literal the literal value;
+ * @return the constraint builder; never null
+ */
+ public ConstraintBuilder literal( BigDecimal literal ) {
+ return comparisonBuilder.is(operator, literal);
+ }
+
+ /**
+ * Define the right-hand side of a comparison.
+ *
+ * @param literal the literal value;
+ * @return the constraint builder; never null
+ */
+ public ConstraintBuilder literal( boolean literal ) {
+ return comparisonBuilder.is(operator, literal);
+ }
+
+ /**
+ * Define the right-hand side of a comparison.
+ *
+ * @param variableName the name of the variable
+ * @return the constraint builder; never null
+ */
+ public ConstraintBuilder variable( String variableName ) {
+ return comparisonBuilder.is(operator, variableName);
+ }
+
+ /**
+ * Define the right-hand side of a comparison.
+ *
+ * @param literal the literal value that is to be cast
+ * @return the constraint builder; never null
+ */
+ public CastAs cast( int literal ) {
+ return new CastAs(this, literal);
+ }
+
+ /**
+ * Define the right-hand side of a comparison.
+ *
+ * @param literal the literal value that is to be cast
+ * @return the constraint builder; never null
+ */
+ public CastAs cast( String literal ) {
+ return new CastAs(this, literal);
+ }
+
+ /**
+ * Define the right-hand side of a comparison.
+ *
+ * @param literal the literal value that is to be cast
+ * @return the constraint builder; never null
+ */
+ public CastAs cast( boolean literal ) {
+ return new CastAs(this, literal);
+ }
+
+ /**
+ * Define the right-hand side of a comparison.
+ *
+ * @param literal the literal value that is to be cast
+ * @return the constraint builder; never null
+ */
+ public CastAs cast( long literal ) {
+ return new CastAs(this, literal);
+ }
+
+ /**
+ * Define the right-hand side of a comparison.
+ *
+ * @param literal the literal value that is to be cast
+ * @return the constraint builder; never null
+ */
+ public CastAs cast( double literal ) {
+ return new CastAs(this, literal);
+ }
+
+ /**
+ * Define the right-hand side of a comparison.
+ *
+ * @param literal the literal value that is to be cast
+ * @return the constraint builder; never null
+ */
+ public CastAs cast( BigDecimal literal ) {
+ return new CastAs(this, literal);
+ }
+
+ /**
+ * Define the right-hand side of a comparison.
+ *
+ * @param literal the literal value that is to be cast
+ * @return the constraint builder; never null
+ */
+ public CastAs cast( DateTime literal ) {
+ return new CastAs(this, literal.toUtcTimeZone());
+ }
+
+ /**
+ * Define the right-hand side of a comparison.
+ *
+ * @param literal the literal value that is to be cast
+ * @return the constraint builder; never null
+ */
+ public CastAs cast( Name literal ) {
+ return new CastAs(this, literal);
+ }
+
+ /**
+ * Define the right-hand side of a comparison.
+ *
+ * @param literal the literal value that is to be cast
+ * @return the constraint builder; never null
+ */
+ public CastAs cast( Path literal ) {
+ return new CastAs(this, literal);
+ }
+
+ /**
+ * Define the right-hand side of a comparison.
+ *
+ * @param literal the literal value that is to be cast
+ * @return the constraint builder; never null
+ */
+ public CastAs cast( UUID literal ) {
+ return new CastAs(this, literal);
+ }
+
+ /**
+ * Define the right-hand side of a comparison.
+ *
+ * @param literal the literal value that is to be cast
+ * @return the constraint builder; never null
+ */
+ public CastAs cast( URI literal ) {
+ return new CastAs(this, literal);
+ }
+ }
+
/**
* An interface used to set the right-hand side of a constraint.
*/
@@ -1192,14 +1693,112 @@
this.constraintBuilder = constraintBuilder;
}
- protected ConstraintBuilder isVariable( Operator operator,
- String variableName ) {
- assert operator != null;
+ /**
+ * Define the operator that will be used in the comparison, returning an interface that can be used to define the
+ * right-hand-side of the comparison.
+ *
+ * @param operator the operator; may not be null
+ * @return the interface used to define the right-hand-side of the comparison
+ */
+ public RightHandSide is( Operator operator ) {
+ CheckArg.isNotNull(operator, "operator");
+ return new RightHandSide(this, operator);
+ }
+
+ /**
+ * Use the 'equal to' operator in the comparison, returning an interface that can be used to define the right-hand-side of
+ * the comparison.
+ *
+ * @return the interface used to define the right-hand-side of the comparison
+ */
+ public RightHandSide isEqualTo() {
+ return is(Operator.EQUAL_TO);
+ }
+
+ /**
+ * Use the 'equal to' operator in the comparison, returning an interface that can be used to define the right-hand-side of
+ * the comparison.
+ *
+ * @return the interface used to define the right-hand-side of the comparison
+ */
+ public RightHandSide isNotEqualTo() {
+ return is(Operator.NOT_EQUAL_TO);
+ }
+
+ /**
+ * Use the 'equal to' operator in the comparison, returning an interface that can be used to define the right-hand-side of
+ * the comparison.
+ *
+ * @return the interface used to define the right-hand-side of the comparison
+ */
+ public RightHandSide isGreaterThan() {
+ return is(Operator.GREATER_THAN);
+ }
+
+ /**
+ * Use the 'equal to' operator in the comparison, returning an interface that can be used to define the right-hand-side of
+ * the comparison.
+ *
+ * @return the interface used to define the right-hand-side of the comparison
+ */
+ public RightHandSide isGreaterThanOrEqualTo() {
+ return is(Operator.GREATER_THAN_OR_EQUAL_TO);
+ }
+
+ /**
+ * Use the 'equal to' operator in the comparison, returning an interface that can be used to define the right-hand-side of
+ * the comparison.
+ *
+ * @return the interface used to define the right-hand-side of the comparison
+ */
+ public RightHandSide isLessThan() {
+ return is(Operator.LESS_THAN);
+ }
+
+ /**
+ * Use the 'equal to' operator in the comparison, returning an interface that can be used to define the right-hand-side of
+ * the comparison.
+ *
+ * @return the interface used to define the right-hand-side of the comparison
+ */
+ public RightHandSide isLessThanOrEqualTo() {
+ return is(Operator.LESS_THAN_OR_EQUAL_TO);
+ }
+
+ /**
+ * Use the 'equal to' operator in the comparison, returning an interface that can be used to define the right-hand-side of
+ * the comparison.
+ *
+ * @return the interface used to define the right-hand-side of the comparison
+ */
+ public RightHandSide isLike() {
+ return is(Operator.LIKE);
+ }
+
+ /**
+ * Define the right-hand-side of the constraint using the supplied operator.
+ *
+ * @param operator the operator; may not be null
+ * @param variableName the name of the variable
+ * @return the builder used to create the constraint clause, ready to be used to create other constraints clauses or
+ * complete already-started clauses; never null
+ */
+ public ConstraintBuilder isVariable( Operator operator,
+ String variableName ) {
+ CheckArg.isNotNull(operator, "operator");
return this.constraintBuilder.setConstraint(new Comparison(left, operator, new BindVariableName(variableName)));
}
- protected ConstraintBuilder is( Operator operator,
- Object literal ) {
+ /**
+ * Define the right-hand-side of the constraint using the supplied operator.
+ *
+ * @param operator the operator; may not be null
+ * @param literal the literal value
+ * @return the builder used to create the constraint clause, ready to be used to create other constraints clauses or
+ * complete already-started clauses; never null
+ */
+ public ConstraintBuilder is( Operator operator,
+ Object literal ) {
assert operator != null;
return this.constraintBuilder.setConstraint(new Comparison(left, operator, new Literal(literal)));
}
Modified: trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/QueryEngine.java
===================================================================
--- trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/QueryEngine.java 2009-10-03 04:07:41 UTC (rev 1285)
+++ trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/QueryEngine.java 2009-10-03 04:09:29 UTC (rev 1286)
@@ -23,11 +23,18 @@
*/
package org.jboss.dna.graph.query;
+import java.util.Collections;
+import java.util.HashSet;
import java.util.List;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.atomic.AtomicBoolean;
import net.jcip.annotations.ThreadSafe;
+import org.jboss.dna.common.text.ParsingException;
import org.jboss.dna.common.util.CheckArg;
import org.jboss.dna.graph.ExecutionContext;
+import org.jboss.dna.graph.GraphI18n;
import org.jboss.dna.graph.query.QueryResults.Statistics;
import org.jboss.dna.graph.query.model.Column;
import org.jboss.dna.graph.query.model.Constraint;
@@ -37,6 +44,8 @@
import org.jboss.dna.graph.query.model.Visitors;
import org.jboss.dna.graph.query.optimize.Optimizer;
import org.jboss.dna.graph.query.optimize.RuleBasedOptimizer;
+import org.jboss.dna.graph.query.parse.InvalidQueryException;
+import org.jboss.dna.graph.query.parse.QueryParser;
import org.jboss.dna.graph.query.plan.CanonicalPlanner;
import org.jboss.dna.graph.query.plan.PlanHints;
import org.jboss.dna.graph.query.plan.PlanNode;
@@ -58,11 +67,13 @@
private final Optimizer optimizer;
private final Processor processor;
private final Schemata schemata;
+ private final ConcurrentMap<String, QueryParser> parsers = new ConcurrentHashMap<String, QueryParser>();
public QueryEngine( Planner planner,
Optimizer optimizer,
Processor processor,
- Schemata schemata ) {
+ Schemata schemata,
+ QueryParser... parsers ) {
CheckArg.isNotNull(processor, "processor");
this.planner = planner != null ? planner : new CanonicalPlanner();
this.optimizer = optimizer != null ? optimizer : new RuleBasedOptimizer();
@@ -74,14 +85,78 @@
return null;
}
};
+ for (QueryParser parser : parsers) {
+ if (parser != null) addLanguage(parser);
+ }
}
/**
+ * Add a language to this engine by supplying its parser.
+ *
+ * @param languageParser the query parser for the language
+ * @throws IllegalArgumentException if the language parser is null
+ */
+ public void addLanguage( QueryParser languageParser ) {
+ CheckArg.isNotNull(languageParser, "languageParser");
+ this.parsers.put(languageParser.getLanguage().toLowerCase(), languageParser);
+ }
+
+ /**
+ * Remove from this engine the language with the given name.
+ *
+ * @param language the name of the language, which is to match the {@link QueryParser#getLanguage() language} of the parser
+ * @return the parser for the language, or null if the engine had no support for the named language
+ * @throws IllegalArgumentException if the language is null
+ */
+ public QueryParser removeLanguage( String language ) {
+ CheckArg.isNotNull(language, "language");
+ return this.parsers.remove(language.toLowerCase());
+ }
+
+ /**
+ * Get the set of languages that this engine is capable of parsing.
+ *
+ * @return the unmodifiable copy of the set of languages; never null but possibly empty
+ */
+ public Set<String> getLanguages() {
+ Set<String> result = new HashSet<String>();
+ for (QueryParser parser : parsers.values()) {
+ result.add(parser.getLanguage());
+ }
+ return Collections.unmodifiableSet(result);
+ }
+
+ /**
* Execute the supplied query by planning, optimizing, and then processing it.
*
* @param context the context in which the query should be executed
+ * @param language the language in which the query is expressed; must be one of the supported {@link #getLanguages()
+ * languages}
* @param query the query that is to be executed
* @return the query results; never null
+ * @throws IllegalArgumentException if the language, context or query references are null, or if the language is not know
+ * @throws ParsingException if there is an error parsing the supplied query
+ * @throws InvalidQueryException if the supplied query can be parsed but is invalid
+ */
+ public QueryResults execute( ExecutionContext context,
+ String language,
+ String query ) {
+ CheckArg.isNotNull(language, "language");
+ CheckArg.isNotNull(context, "context");
+ CheckArg.isNotNull(query, "query");
+ QueryParser parser = parsers.get(language.toLowerCase());
+ if (parser == null) {
+ throw new IllegalArgumentException(GraphI18n.unknownQueryLanguage.text(language));
+ }
+ return execute(context, parser.parseQuery(query, context));
+ }
+
+ /**
+ * Execute the supplied query by planning, optimizing, and then processing it.
+ *
+ * @param context the context in which the query should be executed
+ * @param query the query that is to be executed
+ * @return the query results; never null
* @throws IllegalArgumentException if the context or query references are null
*/
public QueryResults execute( ExecutionContext context,
@@ -101,6 +176,8 @@
public QueryResults execute( ExecutionContext context,
QueryCommand query,
PlanHints hints ) {
+ CheckArg.isNotNull(context, "context");
+ CheckArg.isNotNull(query, "query");
QueryContext queryContext = new QueryContext(context, hints, schemata);
// Create the canonical plan ...
Modified: trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/model/AllNodes.java
===================================================================
--- trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/model/AllNodes.java 2009-10-03 04:07:41 UTC (rev 1285)
+++ trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/model/AllNodes.java 2009-10-03 04:09:29 UTC (rev 1286)
@@ -65,9 +65,10 @@
@Override
public boolean equals( Object obj ) {
if (obj == this) return true;
- if (obj instanceof AllNodes) {
- AllNodes that = (AllNodes)obj;
- return ObjectUtil.isEqualWithNulls(this.getAlias(), that.getAlias());
+ if (obj instanceof Selector) {
+ Selector that = (Selector)obj;
+ return ObjectUtil.isEqualWithNulls(this.getName(), that.getName())
+ && ObjectUtil.isEqualWithNulls(this.getAlias(), that.getAlias());
}
return false;
}
Modified: trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/model/Literal.java
===================================================================
--- trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/model/Literal.java 2009-10-03 04:07:41 UTC (rev 1285)
+++ trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/model/Literal.java 2009-10-03 04:09:29 UTC (rev 1286)
@@ -66,7 +66,7 @@
if (obj == this) return true;
if (obj instanceof Literal) {
Literal that = (Literal)obj;
- return this.value.equals(that.value);
+ return this.value.equals(that.value) || this.value.toString().equals(that.value.toString());
}
return false;
}
Modified: trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/model/NamedSelector.java
===================================================================
--- trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/model/NamedSelector.java 2009-10-03 04:07:41 UTC (rev 1285)
+++ trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/model/NamedSelector.java 2009-10-03 04:09:29 UTC (rev 1286)
@@ -72,8 +72,8 @@
@Override
public boolean equals( Object obj ) {
if (obj == this) return true;
- if (obj instanceof NamedSelector) {
- NamedSelector that = (NamedSelector)obj;
+ if (obj instanceof Selector) {
+ Selector that = (Selector)obj;
if (!this.getName().equals(that.getName())) return false;
if (!ObjectUtil.isEqualWithNulls(this.getAlias(), that.getAlias())) return false;
return true;
Copied: trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/model/NodeDepth.java (from rev 1285, trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/model/Literal.java)
===================================================================
--- trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/model/NodeDepth.java (rev 0)
+++ trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/model/NodeDepth.java 2009-10-03 04:09:29 UTC (rev 1286)
@@ -0,0 +1,90 @@
+/*
+ * JBoss DNA (http://www.jboss.org/dna)
+ * 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.
+ * See the AUTHORS.txt file in the distribution for a full listing of
+ * individual contributors.
+ *
+ * JBoss DNA is free software. Unless otherwise indicated, all code in JBoss DNA
+ * is licensed to you 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.
+ *
+ * JBoss DNA 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 software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.dna.graph.query.model;
+
+import net.jcip.annotations.Immutable;
+import org.jboss.dna.common.util.CheckArg;
+
+/**
+ * A dynamic operand that evaluates to the depth of a node given by a selector, used in a {@link Comparison} constraint.
+ */
+@Immutable
+public class NodeDepth extends DynamicOperand {
+ private final SelectorName selectorName;
+
+ /**
+ * Create a dynamic operand that evaluates to the depth of the node identified by the selector.
+ *
+ * @param selectorName the name of the selector
+ * @throws IllegalArgumentException if the selector name or property name are null
+ */
+ public NodeDepth( SelectorName selectorName ) {
+ CheckArg.isNotNull(selectorName, "selectorName");
+ this.selectorName = selectorName;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.jboss.dna.graph.query.model.DynamicOperand#getSelectorName()
+ */
+ @Override
+ public final SelectorName getSelectorName() {
+ return selectorName;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see java.lang.Object#toString()
+ */
+ @Override
+ public String toString() {
+ return Visitors.readable(this);
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see java.lang.Object#equals(java.lang.Object)
+ */
+ @Override
+ public boolean equals( Object obj ) {
+ if (obj == this) return true;
+ if (obj instanceof NodeDepth) {
+ NodeDepth that = (NodeDepth)obj;
+ return this.selectorName.equals(that.selectorName);
+ }
+ return false;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.jboss.dna.graph.query.model.Visitable#accept(org.jboss.dna.graph.query.model.Visitor)
+ */
+ public void accept( Visitor visitor ) {
+ visitor.visit(this);
+ }
+}
Copied: trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/model/NodePath.java (from rev 1285, trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/model/Literal.java)
===================================================================
--- trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/model/NodePath.java (rev 0)
+++ trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/model/NodePath.java 2009-10-03 04:09:29 UTC (rev 1286)
@@ -0,0 +1,90 @@
+/*
+ * JBoss DNA (http://www.jboss.org/dna)
+ * 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.
+ * See the AUTHORS.txt file in the distribution for a full listing of
+ * individual contributors.
+ *
+ * JBoss DNA is free software. Unless otherwise indicated, all code in JBoss DNA
+ * is licensed to you 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.
+ *
+ * JBoss DNA 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 software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.dna.graph.query.model;
+
+import net.jcip.annotations.Immutable;
+import org.jboss.dna.common.util.CheckArg;
+
+/**
+ * A dynamic operand that evaluates to the path of a node given by a selector, used in a {@link Comparison} constraint.
+ */
+@Immutable
+public class NodePath extends DynamicOperand {
+ private final SelectorName selectorName;
+
+ /**
+ * Create a dynamic operand that evaluates to the path of the node identified by the selector.
+ *
+ * @param selectorName the name of the selector
+ * @throws IllegalArgumentException if the selector name or property name are null
+ */
+ public NodePath( SelectorName selectorName ) {
+ CheckArg.isNotNull(selectorName, "selectorName");
+ this.selectorName = selectorName;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.jboss.dna.graph.query.model.DynamicOperand#getSelectorName()
+ */
+ @Override
+ public final SelectorName getSelectorName() {
+ return selectorName;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see java.lang.Object#toString()
+ */
+ @Override
+ public String toString() {
+ return Visitors.readable(this);
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see java.lang.Object#equals(java.lang.Object)
+ */
+ @Override
+ public boolean equals( Object obj ) {
+ if (obj == this) return true;
+ if (obj instanceof NodePath) {
+ NodePath that = (NodePath)obj;
+ return this.selectorName.equals(that.selectorName);
+ }
+ return false;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.jboss.dna.graph.query.model.Visitable#accept(org.jboss.dna.graph.query.model.Visitor)
+ */
+ public void accept( Visitor visitor ) {
+ visitor.visit(this);
+ }
+}
Modified: trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/model/Operator.java
===================================================================
--- trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/model/Operator.java 2009-10-03 04:07:41 UTC (rev 1285)
+++ trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/model/Operator.java 2009-10-03 04:09:29 UTC (rev 1286)
@@ -64,6 +64,29 @@
}
/**
+ * Get the equivalent operator if the operands are to be reversed.
+ *
+ * @return the reverse operator; never null
+ */
+ public Operator getReverse() {
+ switch (this) {
+ case GREATER_THAN:
+ return LESS_THAN;
+ case GREATER_THAN_OR_EQUAL_TO:
+ return LESS_THAN_OR_EQUAL_TO;
+ case LESS_THAN:
+ return GREATER_THAN;
+ case LESS_THAN_OR_EQUAL_TO:
+ return GREATER_THAN_OR_EQUAL_TO;
+ case EQUAL_TO:
+ case LIKE:
+ case NOT_EQUAL_TO:
+ default:
+ return this;
+ }
+ }
+
+ /**
* {@inheritDoc}
*
* @see java.lang.Enum#toString()
Modified: trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/model/Visitor.java
===================================================================
--- trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/model/Visitor.java 2009-10-03 04:07:41 UTC (rev 1285)
+++ trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/model/Visitor.java 2009-10-03 04:09:29 UTC (rev 1286)
@@ -66,6 +66,10 @@
void visit( NodeName obj );
+ void visit( NodePath obj );
+
+ void visit( NodeDepth obj );
+
void visit( NamedSelector obj );
void visit( Not obj );
Modified: trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/model/Visitors.java
===================================================================
--- trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/model/Visitors.java 2009-10-03 04:07:41 UTC (rev 1285)
+++ trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/model/Visitors.java 2009-10-03 04:09:29 UTC (rev 1286)
@@ -154,6 +154,16 @@
}
@Override
+ public void visit( NodeDepth depth ) {
+ super.visit(depth);
+ }
+
+ @Override
+ public void visit( NodePath path ) {
+ super.visit(path);
+ }
+
+ @Override
public void visit( NodeLocalName node ) {
symbols.add(node.getSelectorName());
}
@@ -348,6 +358,22 @@
/**
* {@inheritDoc}
*
+ * @see org.jboss.dna.graph.query.model.Visitor#visit(org.jboss.dna.graph.query.model.NodeDepth)
+ */
+ public void visit( NodeDepth obj ) {
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.jboss.dna.graph.query.model.Visitor#visit(org.jboss.dna.graph.query.model.NodePath)
+ */
+ public void visit( NodePath obj ) {
+ }
+
+ /**
+ * {@inheritDoc}
+ *
* @see org.jboss.dna.graph.query.model.Visitor#visit(org.jboss.dna.graph.query.model.NodeName)
*/
public void visit( NodeName obj ) {
@@ -689,6 +715,26 @@
/**
* {@inheritDoc}
*
+ * @see org.jboss.dna.graph.query.model.Visitor#visit(org.jboss.dna.graph.query.model.NodeDepth)
+ */
+ public void visit( NodeDepth depth ) {
+ strategy.visit(depth);
+ visitNext();
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.jboss.dna.graph.query.model.Visitor#visit(org.jboss.dna.graph.query.model.NodePath)
+ */
+ public void visit( NodePath path ) {
+ strategy.visit(path);
+ visitNext();
+ }
+
+ /**
+ * {@inheritDoc}
+ *
* @see org.jboss.dna.graph.query.model.Visitor#visit(org.jboss.dna.graph.query.model.NodeName)
*/
public void visit( NodeName nodeName ) {
@@ -1098,8 +1144,15 @@
* @see org.jboss.dna.graph.query.model.Visitor#visit(org.jboss.dna.graph.query.model.Literal)
*/
public void visit( Literal literal ) {
- if (context == null) append(literal.getValue().toString());
- else append(context.getValueFactories().getStringFactory().create(literal.getValue()));
+ Object value = literal.getValue();
+ boolean quote = value instanceof String || value instanceof Path || value instanceof Name;
+ if (quote) append('\'');
+ if (context == null) {
+ append(literal.getValue().toString());
+ } else {
+ append(context.getValueFactories().getStringFactory().create(literal.getValue()));
+ }
+ if (quote) append('\'');
}
/**
@@ -1116,6 +1169,24 @@
/**
* {@inheritDoc}
*
+ * @see org.jboss.dna.graph.query.model.Visitor#visit(org.jboss.dna.graph.query.model.NodeDepth)
+ */
+ public void visit( NodeDepth depth ) {
+ append("DEPTH(").append(depth.getSelectorName()).append(')');
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.jboss.dna.graph.query.model.Visitor#visit(org.jboss.dna.graph.query.model.NodePath)
+ */
+ public void visit( NodePath path ) {
+ append("PATH(").append(path.getSelectorName()).append(')');
+ }
+
+ /**
+ * {@inheritDoc}
+ *
* @see org.jboss.dna.graph.query.model.Visitor#visit(org.jboss.dna.graph.query.model.NodeLocalName)
*/
public void visit( NodeLocalName name ) {
Modified: trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/optimize/RewriteIdentityJoins.java
===================================================================
--- trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/optimize/RewriteIdentityJoins.java 2009-10-03 04:07:41 UTC (rev 1285)
+++ trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/optimize/RewriteIdentityJoins.java 2009-10-03 04:09:29 UTC (rev 1286)
@@ -49,8 +49,10 @@
import org.jboss.dna.graph.query.model.JoinCondition;
import org.jboss.dna.graph.query.model.Length;
import org.jboss.dna.graph.query.model.LowerCase;
+import org.jboss.dna.graph.query.model.NodeDepth;
import org.jboss.dna.graph.query.model.NodeLocalName;
import org.jboss.dna.graph.query.model.NodeName;
+import org.jboss.dna.graph.query.model.NodePath;
import org.jboss.dna.graph.query.model.Not;
import org.jboss.dna.graph.query.model.Or;
import org.jboss.dna.graph.query.model.Ordering;
@@ -338,8 +340,20 @@
PropertyValue value = (PropertyValue)operand;
SelectorName replacement = rewrittenSelectors.get(value.getSelectorName());
if (replacement == null) return operand;
- return new Length(new PropertyValue(replacement, value.getPropertyName()));
+ return new PropertyValue(replacement, value.getPropertyName());
}
+ if (operand instanceof NodeDepth) {
+ NodeDepth depth = (NodeDepth)operand;
+ SelectorName replacement = rewrittenSelectors.get(depth.getSelectorName());
+ if (replacement == null) return operand;
+ return new NodeDepth(replacement);
+ }
+ if (operand instanceof NodePath) {
+ NodePath path = (NodePath)operand;
+ SelectorName replacement = rewrittenSelectors.get(path.getSelectorName());
+ if (replacement == null) return operand;
+ return new NodePath(replacement);
+ }
return operand;
}
Copied: trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/parse/InvalidQueryException.java (from rev 1285, trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/InvalidQueryException.java)
===================================================================
--- trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/parse/InvalidQueryException.java (rev 0)
+++ trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/parse/InvalidQueryException.java 2009-10-03 04:09:29 UTC (rev 1286)
@@ -0,0 +1,71 @@
+/*
+ * JBoss DNA (http://www.jboss.org/dna)
+ * 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.
+ * See the AUTHORS.txt file in the distribution for a full listing of
+ * individual contributors.
+ *
+ * JBoss DNA is free software. Unless otherwise indicated, all code in JBoss DNA
+ * is licensed to you 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.
+ *
+ * JBoss DNA 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 software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.dna.graph.query.parse;
+
+import org.jboss.dna.common.util.CheckArg;
+
+/**
+ * An exception signalling that an XPath query is invalid (but typically well-formed)
+ */
+public class InvalidQueryException extends RuntimeException {
+
+ /**
+ */
+ private static final long serialVersionUID = 1L;
+
+ private final String xpath;
+
+ /**
+ * Create an exception with the invalid query.
+ *
+ * @param xpath the XPath query that is invalid
+ */
+ public InvalidQueryException( String xpath ) {
+ super();
+ this.xpath = xpath;
+ }
+
+ /**
+ * Create an exception with the invalid query and a message.
+ *
+ * @param xpath the XPath query that is invalid
+ * @param message
+ */
+ public InvalidQueryException( String xpath,
+ String message ) {
+ super(message);
+ CheckArg.isNotNull(xpath, "xpath");
+ this.xpath = xpath;
+ }
+
+ /**
+ * Get the XPath query that is invalid.
+ *
+ * @return the query
+ */
+ public String getXPath() {
+ return xpath;
+ }
+
+}
Property changes on: trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/parse/InvalidQueryException.java
___________________________________________________________________
Name: svn:keywords
+ Id Revision
Name: svn:eol-style
+ LF
Modified: trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/parse/QueryParser.java
===================================================================
--- trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/parse/QueryParser.java 2009-10-03 04:07:41 UTC (rev 1285)
+++ trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/parse/QueryParser.java 2009-10-03 04:09:29 UTC (rev 1286)
@@ -23,22 +23,34 @@
*/
package org.jboss.dna.graph.query.parse;
+import net.jcip.annotations.Immutable;
+import org.jboss.dna.common.text.ParsingException;
import org.jboss.dna.graph.ExecutionContext;
import org.jboss.dna.graph.query.model.QueryCommand;
/**
* The basic interface defining a component that is able to parse a string query into a {@link QueryCommand}.
*/
+@Immutable
public interface QueryParser {
/**
+ * Get the name of the language that this parser is able to understand.
+ *
+ * @return the language name; never null
+ */
+ String getLanguage();
+
+ /**
* Parse the supplied query from a string representation into a {@link QueryCommand}.
*
* @param query the query in string form; may not be null
* @param context the context in which the query is being parsed
* @return the query command
+ * @throws ParsingException if there is an error parsing the supplied query
+ * @throws InvalidQueryException if the supplied query can be parsed but is invalid
*/
QueryCommand parseQuery( String query,
- ExecutionContext context );
+ ExecutionContext context ) throws InvalidQueryException;
}
Modified: trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/parse/SqlQueryParser.java
===================================================================
--- trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/parse/SqlQueryParser.java 2009-10-03 04:07:41 UTC (rev 1285)
+++ trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/parse/SqlQueryParser.java 2009-10-03 04:09:29 UTC (rev 1286)
@@ -67,8 +67,10 @@
import org.jboss.dna.graph.query.model.Literal;
import org.jboss.dna.graph.query.model.LowerCase;
import org.jboss.dna.graph.query.model.NamedSelector;
+import org.jboss.dna.graph.query.model.NodeDepth;
import org.jboss.dna.graph.query.model.NodeLocalName;
import org.jboss.dna.graph.query.model.NodeName;
+import org.jboss.dna.graph.query.model.NodePath;
import org.jboss.dna.graph.query.model.Not;
import org.jboss.dna.graph.query.model.Operator;
import org.jboss.dna.graph.query.model.Or;
@@ -102,9 +104,20 @@
*/
public class SqlQueryParser implements QueryParser {
+ public static final String LANGUAGE = "SQL";
+
/**
* {@inheritDoc}
*
+ * @see org.jboss.dna.graph.query.parse.QueryParser#getLanguage()
+ */
+ public String getLanguage() {
+ return LANGUAGE;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
* @see org.jboss.dna.graph.query.parse.QueryParser#parseQuery(String, ExecutionContext)
*/
public QueryCommand parseQuery( String query,
@@ -188,12 +201,12 @@
List<ColumnExpression> columns = new ArrayList<ColumnExpression>();
do {
Position position = tokens.nextPosition();
- String propertyName = tokens.consume();
+ String propertyName = removeBracketsAndQuotes(tokens.consume());
SelectorName selectorName = null;
if (tokens.canConsume('.')) {
// We actually read the selector name, so now read the property name ...
selectorName = new SelectorName(propertyName);
- propertyName = tokens.consume();
+ propertyName = removeBracketsAndQuotes(tokens.consume());
}
String alias = propertyName;
if (tokens.canConsume("AS")) alias = removeBracketsAndQuotes(tokens.consume());
@@ -304,7 +317,7 @@
propertyName = parseName(tokens, context);
} else {
if (!(source instanceof Selector)) {
- String msg = GraphI18n.functionIsAmbiguous.text("CONTEXT()", pos.getLine(), pos.getColumn());
+ String msg = GraphI18n.functionIsAmbiguous.text("CONTAINS()", pos.getLine(), pos.getColumn());
throw new ParsingException(pos, msg);
}
selectorName = ((Selector)source).getName();
@@ -681,6 +694,26 @@
}
result = new FullTextSearchScore(parseSelectorName(tokens));
tokens.consume(")");
+ } else if (tokens.canConsume("DEPTH", "(")) {
+ if (tokens.canConsume(")")) {
+ if (source instanceof Selector) {
+ return new NodeDepth(((Selector)source).getName());
+ }
+ String msg = GraphI18n.functionIsAmbiguous.text("DEPTH()", pos.getLine(), pos.getColumn());
+ throw new ParsingException(pos, msg);
+ }
+ result = new NodeDepth(parseSelectorName(tokens));
+ tokens.consume(")");
+ } else if (tokens.canConsume("PATH", "(")) {
+ if (tokens.canConsume(")")) {
+ if (source instanceof Selector) {
+ return new NodePath(((Selector)source).getName());
+ }
+ String msg = GraphI18n.functionIsAmbiguous.text("PATH()", pos.getLine(), pos.getColumn());
+ throw new ParsingException(pos, msg);
+ }
+ result = new NodePath(parseSelectorName(tokens));
+ tokens.consume(")");
} else {
result = parsePropertyValue(tokens, context, source);
}
@@ -743,7 +776,19 @@
* quotes
*/
protected String removeBracketsAndQuotes( String text ) {
- return text.replaceFirst("^['\"\\[]+", "").replaceAll("['\"\\]]+$", "");
+ if (text.length() > 0) {
+ char firstChar = text.charAt(0);
+ switch (firstChar) {
+ case '\'':
+ case '"':
+ assert text.charAt(text.length() - 1) == firstChar;
+ return removeBracketsAndQuotes(text.substring(1, text.length() - 1));
+ case '[':
+ assert text.charAt(text.length() - 1) == ']';
+ return removeBracketsAndQuotes(text.substring(1, text.length() - 1));
+ }
+ }
+ return text;
}
protected NamedSelector parseNamedSelector( TokenStream tokens ) {
Modified: trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/process/ProcessingComponent.java
===================================================================
--- trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/process/ProcessingComponent.java 2009-10-03 04:07:41 UTC (rev 1285)
+++ trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/process/ProcessingComponent.java 2009-10-03 04:09:29 UTC (rev 1286)
@@ -40,8 +40,10 @@
import org.jboss.dna.graph.query.model.FullTextSearchScore;
import org.jboss.dna.graph.query.model.Length;
import org.jboss.dna.graph.query.model.LowerCase;
+import org.jboss.dna.graph.query.model.NodeDepth;
import org.jboss.dna.graph.query.model.NodeLocalName;
import org.jboss.dna.graph.query.model.NodeName;
+import org.jboss.dna.graph.query.model.NodePath;
import org.jboss.dna.graph.query.model.PropertyValue;
import org.jboss.dna.graph.query.model.UpperCase;
import org.jboss.dna.graph.query.validate.Schemata.Column;
@@ -219,6 +221,40 @@
}
};
}
+ if (operand instanceof NodeDepth) {
+ NodeDepth nodeDepth = (NodeDepth)operand;
+ final int locationIndex = columns.getLocationIndex(nodeDepth.getSelectorName().getName());
+ return new DynamicOperation() {
+ public PropertyType getExpectedType() {
+ return PropertyType.LONG;
+ }
+
+ public Object evaluate( Object[] tuple ) {
+ Location location = (Location)tuple[locationIndex];
+ if (location == null) return null;
+ Path path = location.getPath();
+ assert path != null;
+ return new Long(path.size());
+ }
+ };
+ }
+ if (operand instanceof NodePath) {
+ NodePath nodePath = (NodePath)operand;
+ final int locationIndex = columns.getLocationIndex(nodePath.getSelectorName().getName());
+ return new DynamicOperation() {
+ public PropertyType getExpectedType() {
+ return PropertyType.PATH;
+ }
+
+ public Object evaluate( Object[] tuple ) {
+ Location location = (Location)tuple[locationIndex];
+ if (location == null) return null;
+ Path path = location.getPath();
+ assert path != null;
+ return path;
+ }
+ };
+ }
if (operand instanceof NodeName) {
NodeName nodeName = (NodeName)operand;
final int locationIndex = columns.getLocationIndex(nodeName.getSelectorName().getName());
Modified: trunk/dna-graph/src/main/resources/org/jboss/dna/graph/GraphI18n.properties
===================================================================
--- trunk/dna-graph/src/main/resources/org/jboss/dna/graph/GraphI18n.properties 2009-10-03 04:07:41 UTC (rev 1285)
+++ trunk/dna-graph/src/main/resources/org/jboss/dna/graph/GraphI18n.properties 2009-10-03 04:09:29 UTC (rev 1286)
@@ -116,6 +116,7 @@
childNotFound = Child "{0}" could not be found under "{1}" in workspace "{2}"
# Query
+unknownQueryLanguage = '{0}' is not a known query language
tableDoesNotExist = Table '{0}' does not exist
columnDoesNotExistOnTable = Column '{0}' does not exist on the table '{1}'
columnDoesNotExistInQuery = Column '{0}' does not exist in query
Modified: trunk/dna-graph/src/test/java/org/jboss/dna/graph/query/QueryBuilderTest.java
===================================================================
--- trunk/dna-graph/src/test/java/org/jboss/dna/graph/query/QueryBuilderTest.java 2009-10-03 04:07:41 UTC (rev 1285)
+++ trunk/dna-graph/src/test/java/org/jboss/dna/graph/query/QueryBuilderTest.java 2009-10-03 04:09:29 UTC (rev 1286)
@@ -433,7 +433,7 @@
.end()
.query();
assertThatSql(query, is("SELECT * FROM table AS nodes " + //
- "WHERE LENGTH(nodes.property) = literal"));
+ "WHERE LENGTH(nodes.property) = 'literal'"));
}
@Test
@@ -459,7 +459,7 @@
.end()
.query();
assertThatSql(query, is("SELECT * FROM table AS nodes " + //
- "WHERE LENGTH(nodes.property) != literal"));
+ "WHERE LENGTH(nodes.property) != 'literal'"));
}
@Test
@@ -485,7 +485,7 @@
.end()
.query();
assertThatSql(query, is("SELECT * FROM table AS nodes " + //
- "WHERE LENGTH(nodes.property) < literal"));
+ "WHERE LENGTH(nodes.property) < 'literal'"));
}
@Test
@@ -511,7 +511,7 @@
.end()
.query();
assertThatSql(query, is("SELECT * FROM table AS nodes " + //
- "WHERE LENGTH(nodes.property) <= literal"));
+ "WHERE LENGTH(nodes.property) <= 'literal'"));
}
@Test
@@ -537,7 +537,7 @@
.end()
.query();
assertThatSql(query, is("SELECT * FROM table AS nodes " + //
- "WHERE LENGTH(nodes.property) > literal"));
+ "WHERE LENGTH(nodes.property) > 'literal'"));
}
@Test
@@ -563,7 +563,7 @@
.end()
.query();
assertThatSql(query, is("SELECT * FROM table AS nodes " + //
- "WHERE LENGTH(nodes.property) >= literal"));
+ "WHERE LENGTH(nodes.property) >= 'literal'"));
}
@Test
@@ -583,7 +583,7 @@
public void shouldBuildQueryWithCriteriaUsingLengthLike() {
query = builder.selectStar().from("table AS nodes").where().length("nodes", "property").isLike("literal").end().query();
assertThatSql(query, is("SELECT * FROM table AS nodes " + //
- "WHERE LENGTH(nodes.property) LIKE literal"));
+ "WHERE LENGTH(nodes.property) LIKE 'literal'"));
}
@Test
@@ -600,10 +600,44 @@
}
@Test
+ public void shouldBuildQueryWithCriteriaUsingNodeDepthEqualToLiteral() {
+ query = builder.selectStar().from("table AS nodes").where().depth("nodes").isEqualTo(3).end().query();
+ assertThatSql(query, is("SELECT * FROM table AS nodes " + //
+ "WHERE DEPTH(nodes) = 3"));
+ }
+
+ @Test
+ public void shouldBuildQueryWithCriteriaUsingNodeDepthLessThanOrEqualToLongLiteral() {
+ query = builder.selectStar().from("table AS nodes").where().depth("nodes").isLessThanOrEqualTo(3).end().query();
+ assertThatSql(query, is("SELECT * FROM table AS nodes " + //
+ "WHERE DEPTH(nodes) <= 3"));
+ }
+
+ @Test
+ public void shouldBuildQueryWithCriteriaUsingNodeDepthLessThanOrEqualToStringLiteral() {
+ query = builder.selectStar().from("table AS nodes").where().depth("nodes").isLessThanOrEqualTo(3).end().query();
+ assertThatSql(query, is("SELECT * FROM table AS nodes " + //
+ "WHERE DEPTH(nodes) <= 3"));
+ }
+
+ @Test
+ public void shouldBuildQueryWithCriteriaUsingNodeDepthLessThanOrEqualToVariable() {
+ query = builder.selectStar()
+ .from("table AS nodes")
+ .where()
+ .depth("nodes")
+ .isLessThanOrEqualToVariable("value")
+ .end()
+ .query();
+ assertThatSql(query, is("SELECT * FROM table AS nodes " + //
+ "WHERE DEPTH(nodes) <= $value"));
+ }
+
+ @Test
public void shouldBuildQueryWithCriteriaUsingNodeNameEqualTo() {
query = builder.selectStar().from("table AS nodes").where().nodeName("nodes").isEqualTo("literal").end().query();
assertThatSql(query, is("SELECT * FROM table AS nodes " + //
- "WHERE NAME(nodes) = literal"));
+ "WHERE NAME(nodes) = 'literal'"));
}
@Test
@@ -617,7 +651,7 @@
public void shouldBuildQueryWithCriteriaUsingNodeNameNotEqualTo() {
query = builder.selectStar().from("table AS nodes").where().nodeName("nodes").isNotEqualTo("literal").end().query();
assertThatSql(query, is("SELECT * FROM table AS nodes " + //
- "WHERE NAME(nodes) != literal"));
+ "WHERE NAME(nodes) != 'literal'"));
}
@Test
@@ -637,7 +671,7 @@
public void shouldBuildQueryWithCriteriaUsingNodeNameLessThan() {
query = builder.selectStar().from("table AS nodes").where().nodeName("nodes").isLessThan("literal").end().query();
assertThatSql(query, is("SELECT * FROM table AS nodes " + //
- "WHERE NAME(nodes) < literal"));
+ "WHERE NAME(nodes) < 'literal'"));
}
@Test
@@ -657,7 +691,7 @@
.end()
.query();
assertThatSql(query, is("SELECT * FROM table AS nodes " + //
- "WHERE NAME(nodes) <= literal"));
+ "WHERE NAME(nodes) <= 'literal'"));
}
@Test
@@ -677,7 +711,7 @@
public void shouldBuildQueryWithCriteriaUsingNodeNameGreaterThan() {
query = builder.selectStar().from("table AS nodes").where().nodeName("nodes").isGreaterThan("literal").end().query();
assertThatSql(query, is("SELECT * FROM table AS nodes " + //
- "WHERE NAME(nodes) > literal"));
+ "WHERE NAME(nodes) > 'literal'"));
}
@Test
@@ -703,7 +737,7 @@
.end()
.query();
assertThatSql(query, is("SELECT * FROM table AS nodes " + //
- "WHERE NAME(nodes) >= literal"));
+ "WHERE NAME(nodes) >= 'literal'"));
}
@Test
@@ -723,7 +757,7 @@
public void shouldBuildQueryWithCriteriaUsingNodeNameLike() {
query = builder.selectStar().from("table AS nodes").where().nodeName("nodes").isLike("literal").end().query();
assertThatSql(query, is("SELECT * FROM table AS nodes " + //
- "WHERE NAME(nodes) LIKE literal"));
+ "WHERE NAME(nodes) LIKE 'literal'"));
}
@Test
@@ -737,7 +771,7 @@
public void shouldBuildQueryWithCriteriaUsingNodeLocalNameEqualTo() {
query = builder.selectStar().from("table AS nodes").where().nodeLocalName("nodes").isEqualTo("literal").end().query();
assertThatSql(query, is("SELECT * FROM table AS nodes " + //
- "WHERE LOCALNAME(nodes) = literal"));
+ "WHERE LOCALNAME(nodes) = 'literal'"));
}
@Test
@@ -757,7 +791,7 @@
public void shouldBuildQueryWithCriteriaUsingNodeLocalNameNotEqualTo() {
query = builder.selectStar().from("table AS nodes").where().nodeLocalName("nodes").isNotEqualTo("literal").end().query();
assertThatSql(query, is("SELECT * FROM table AS nodes " + //
- "WHERE LOCALNAME(nodes) != literal"));
+ "WHERE LOCALNAME(nodes) != 'literal'"));
}
@Test
@@ -777,7 +811,7 @@
public void shouldBuildQueryWithCriteriaUsingNodeLocalNameLessThan() {
query = builder.selectStar().from("table AS nodes").where().nodeLocalName("nodes").isLessThan("literal").end().query();
assertThatSql(query, is("SELECT * FROM table AS nodes " + //
- "WHERE LOCALNAME(nodes) < literal"));
+ "WHERE LOCALNAME(nodes) < 'literal'"));
}
@Test
@@ -803,7 +837,7 @@
.end()
.query();
assertThatSql(query, is("SELECT * FROM table AS nodes " + //
- "WHERE LOCALNAME(nodes) <= literal"));
+ "WHERE LOCALNAME(nodes) <= 'literal'"));
}
@Test
@@ -823,7 +857,7 @@
public void shouldBuildQueryWithCriteriaUsingNodeLocalNameGreaterThan() {
query = builder.selectStar().from("table AS nodes").where().nodeLocalName("nodes").isGreaterThan("literal").end().query();
assertThatSql(query, is("SELECT * FROM table AS nodes " + //
- "WHERE LOCALNAME(nodes) > literal"));
+ "WHERE LOCALNAME(nodes) > 'literal'"));
}
@Test
@@ -849,7 +883,7 @@
.end()
.query();
assertThatSql(query, is("SELECT * FROM table AS nodes " + //
- "WHERE LOCALNAME(nodes) >= literal"));
+ "WHERE LOCALNAME(nodes) >= 'literal'"));
}
@Test
@@ -869,7 +903,7 @@
public void shouldBuildQueryWithCriteriaUsingNodeLocalNameLike() {
query = builder.selectStar().from("table AS nodes").where().nodeLocalName("nodes").isLike("literal").end().query();
assertThatSql(query, is("SELECT * FROM table AS nodes " + //
- "WHERE LOCALNAME(nodes) LIKE literal"));
+ "WHERE LOCALNAME(nodes) LIKE 'literal'"));
}
@Test
@@ -896,7 +930,7 @@
.end()
.query();
assertThatSql(query, is("SELECT * FROM table AS nodes " + //
- "WHERE UPPER(NAME(nodes)) = literal"));
+ "WHERE UPPER(NAME(nodes)) = 'literal'"));
}
@Test
@@ -924,7 +958,7 @@
.end()
.query();
assertThatSql(query, is("SELECT * FROM table AS nodes " + //
- "WHERE UPPER(NAME(nodes)) != literal"));
+ "WHERE UPPER(NAME(nodes)) != 'literal'"));
}
@Test
@@ -952,7 +986,7 @@
.end()
.query();
assertThatSql(query, is("SELECT * FROM table AS nodes " + //
- "WHERE UPPER(NAME(nodes)) < literal"));
+ "WHERE UPPER(NAME(nodes)) < 'literal'"));
}
@Test
@@ -980,7 +1014,7 @@
.end()
.query();
assertThatSql(query, is("SELECT * FROM table AS nodes " + //
- "WHERE UPPER(NAME(nodes)) <= literal"));
+ "WHERE UPPER(NAME(nodes)) <= 'literal'"));
}
@Test
@@ -1008,7 +1042,7 @@
.end()
.query();
assertThatSql(query, is("SELECT * FROM table AS nodes " + //
- "WHERE UPPER(NAME(nodes)) > literal"));
+ "WHERE UPPER(NAME(nodes)) > 'literal'"));
}
@Test
@@ -1036,7 +1070,7 @@
.end()
.query();
assertThatSql(query, is("SELECT * FROM table AS nodes " + //
- "WHERE UPPER(NAME(nodes)) >= literal"));
+ "WHERE UPPER(NAME(nodes)) >= 'literal'"));
}
@Test
@@ -1064,7 +1098,7 @@
.end()
.query();
assertThatSql(query, is("SELECT * FROM table AS nodes " + //
- "WHERE UPPER(NAME(nodes)) LIKE literal"));
+ "WHERE UPPER(NAME(nodes)) LIKE 'literal'"));
}
@Test
@@ -1092,7 +1126,7 @@
.end()
.query();
assertThatSql(query, is("SELECT * FROM table AS nodes " + //
- "WHERE LOWER(NAME(nodes)) = literal"));
+ "WHERE LOWER(NAME(nodes)) = 'literal'"));
}
@Test
@@ -1120,7 +1154,7 @@
.end()
.query();
assertThatSql(query, is("SELECT * FROM table AS nodes " + //
- "WHERE LOWER(NAME(nodes)) != literal"));
+ "WHERE LOWER(NAME(nodes)) != 'literal'"));
}
@Test
@@ -1148,7 +1182,7 @@
.end()
.query();
assertThatSql(query, is("SELECT * FROM table AS nodes " + //
- "WHERE LOWER(NAME(nodes)) < literal"));
+ "WHERE LOWER(NAME(nodes)) < 'literal'"));
}
@Test
@@ -1176,7 +1210,7 @@
.end()
.query();
assertThatSql(query, is("SELECT * FROM table AS nodes " + //
- "WHERE LOWER(NAME(nodes)) <= literal"));
+ "WHERE LOWER(NAME(nodes)) <= 'literal'"));
}
@Test
@@ -1204,7 +1238,7 @@
.end()
.query();
assertThatSql(query, is("SELECT * FROM table AS nodes " + //
- "WHERE LOWER(NAME(nodes)) > literal"));
+ "WHERE LOWER(NAME(nodes)) > 'literal'"));
}
@Test
@@ -1232,7 +1266,7 @@
.end()
.query();
assertThatSql(query, is("SELECT * FROM table AS nodes " + //
- "WHERE LOWER(NAME(nodes)) >= literal"));
+ "WHERE LOWER(NAME(nodes)) >= 'literal'"));
}
@Test
@@ -1260,7 +1294,7 @@
.end()
.query();
assertThatSql(query, is("SELECT * FROM table AS nodes " + //
- "WHERE LOWER(NAME(nodes)) LIKE literal"));
+ "WHERE LOWER(NAME(nodes)) LIKE 'literal'"));
}
@Test
@@ -1289,6 +1323,6 @@
.end()
.query();
assertThatSql(query, is("SELECT * FROM table AS nodes " + //
- "WHERE LOWER(UPPER(NAME(nodes))) = literal"));
+ "WHERE LOWER(UPPER(NAME(nodes))) = 'literal'"));
}
}
Modified: trunk/dna-graph/src/test/java/org/jboss/dna/graph/query/parse/SqlQueryParserTest.java
===================================================================
--- trunk/dna-graph/src/test/java/org/jboss/dna/graph/query/parse/SqlQueryParserTest.java 2009-10-03 04:07:41 UTC (rev 1285)
+++ trunk/dna-graph/src/test/java/org/jboss/dna/graph/query/parse/SqlQueryParserTest.java 2009-10-03 04:09:29 UTC (rev 1286)
@@ -52,8 +52,10 @@
import org.jboss.dna.graph.query.model.Literal;
import org.jboss.dna.graph.query.model.LowerCase;
import org.jboss.dna.graph.query.model.NamedSelector;
+import org.jboss.dna.graph.query.model.NodeDepth;
import org.jboss.dna.graph.query.model.NodeLocalName;
import org.jboss.dna.graph.query.model.NodeName;
+import org.jboss.dna.graph.query.model.NodePath;
import org.jboss.dna.graph.query.model.Not;
import org.jboss.dna.graph.query.model.Operator;
import org.jboss.dna.graph.query.model.Or;
@@ -1229,6 +1231,88 @@
}
// ----------------------------------------------------------------------------------------------------------------
+ // parseDynamicOperand - DEPTH
+ // ----------------------------------------------------------------------------------------------------------------
+
+ @Test
+ public void shouldParseDynamicOperandFromStringContainingDepthOfSelector() {
+ DynamicOperand operand = parser.parseDynamicOperand(tokens("DEPTH(tableA)"), context, mock(Source.class));
+ assertThat(operand, is(instanceOf(NodeDepth.class)));
+ NodeDepth depth = (NodeDepth)operand;
+ assertThat(depth.getSelectorName(), is(selectorName("tableA")));
+ }
+
+ @Test
+ public void shouldParseDynamicOperandFromStringContainingDepthWithNoSelectorOnlyIfThereIsOneSelectorAsSource() {
+ Source source = new NamedSelector(selectorName("tableA"));
+ DynamicOperand operand = parser.parseDynamicOperand(tokens("DEPTH()"), context, source);
+ assertThat(operand, is(instanceOf(NodeDepth.class)));
+ NodeDepth depth = (NodeDepth)operand;
+ assertThat(depth.getSelectorName(), is(selectorName("tableA")));
+ }
+
+ @Test( expected = ParsingException.class )
+ public void shouldFailToParseDynamicOperandFromStringContainingDepthWithNoSelectorIfTheSourceIsNotASelector() {
+ parser.parseDynamicOperand(tokens("DEPTH()"), context, mock(Source.class));
+ }
+
+ @Test( expected = ParsingException.class )
+ public void shouldFailToParseDynamicOperandFromStringContainingDepthWithSelectorNameAndProperty() {
+ parser.parseDynamicOperand(tokens("DEPTH(tableA.property) other"), context, mock(Source.class));
+ }
+
+ @Test( expected = ParsingException.class )
+ public void shouldFailToParseDynamicOperandFromStringContainingDepthWithoutClosingParenthesis() {
+ parser.parseDynamicOperand(tokens("DEPTH(tableA other"), context, mock(Source.class));
+ }
+
+ @Test( expected = ParsingException.class )
+ public void shouldFailToParseDynamicOperandFromStringContainingDepthWithoutOpeningParenthesis() {
+ parser.parseDynamicOperand(tokens("Depth tableA other"), context, mock(Source.class));
+ }
+
+ // ----------------------------------------------------------------------------------------------------------------
+ // parseDynamicOperand - PATH
+ // ----------------------------------------------------------------------------------------------------------------
+
+ @Test
+ public void shouldParseDynamicOperandFromStringContainingPathOfSelector() {
+ DynamicOperand operand = parser.parseDynamicOperand(tokens("PATH(tableA)"), context, mock(Source.class));
+ assertThat(operand, is(instanceOf(NodePath.class)));
+ NodePath path = (NodePath)operand;
+ assertThat(path.getSelectorName(), is(selectorName("tableA")));
+ }
+
+ @Test
+ public void shouldParseDynamicOperandFromStringContainingPathWithNoSelectorOnlyIfThereIsOneSelectorAsSource() {
+ Source source = new NamedSelector(selectorName("tableA"));
+ DynamicOperand operand = parser.parseDynamicOperand(tokens("PATH()"), context, source);
+ assertThat(operand, is(instanceOf(NodePath.class)));
+ NodePath path = (NodePath)operand;
+ assertThat(path.getSelectorName(), is(selectorName("tableA")));
+ }
+
+ @Test( expected = ParsingException.class )
+ public void shouldFailToParseDynamicOperandFromStringContainingPathWithNoSelectorIfTheSourceIsNotASelector() {
+ parser.parseDynamicOperand(tokens("PATH()"), context, mock(Source.class));
+ }
+
+ @Test( expected = ParsingException.class )
+ public void shouldFailToParseDynamicOperandFromStringContainingPathWithSelectorNameAndProperty() {
+ parser.parseDynamicOperand(tokens("PATH(tableA.property) other"), context, mock(Source.class));
+ }
+
+ @Test( expected = ParsingException.class )
+ public void shouldFailToParseDynamicOperandFromStringContainingPathWithoutClosingParenthesis() {
+ parser.parseDynamicOperand(tokens("PATH(tableA other"), context, mock(Source.class));
+ }
+
+ @Test( expected = ParsingException.class )
+ public void shouldFailToParseDynamicOperandFromStringContainingPathWithoutOpeningParenthesis() {
+ parser.parseDynamicOperand(tokens("Path tableA other"), context, mock(Source.class));
+ }
+
+ // ----------------------------------------------------------------------------------------------------------------
// parseDynamicOperand - NAME
// ----------------------------------------------------------------------------------------------------------------
Modified: trunk/dna-graph/src/test/java/org/jboss/dna/graph/query/process/AbstractQueryResultsTest.java
===================================================================
--- trunk/dna-graph/src/test/java/org/jboss/dna/graph/query/process/AbstractQueryResultsTest.java 2009-10-03 04:07:41 UTC (rev 1285)
+++ trunk/dna-graph/src/test/java/org/jboss/dna/graph/query/process/AbstractQueryResultsTest.java 2009-10-03 04:09:29 UTC (rev 1286)
@@ -37,13 +37,14 @@
import org.jboss.dna.graph.query.model.Column;
import org.jboss.dna.graph.query.model.FullTextSearchScore;
import org.jboss.dna.graph.query.model.Length;
+import org.jboss.dna.graph.query.model.NodeDepth;
import org.jboss.dna.graph.query.model.NodeLocalName;
import org.jboss.dna.graph.query.model.NodeName;
+import org.jboss.dna.graph.query.model.NodePath;
import org.jboss.dna.graph.query.model.Order;
import org.jboss.dna.graph.query.model.Ordering;
import org.jboss.dna.graph.query.model.PropertyValue;
import org.jboss.dna.graph.query.model.SelectorName;
-import org.jboss.dna.graph.query.process.QueryResultColumns;
import org.jboss.dna.graph.query.validate.ImmutableSchemata;
import org.jboss.dna.graph.query.validate.Schemata;
@@ -209,6 +210,24 @@
return new Ordering(new Length(new PropertyValue(column.getSelectorName(), column.getPropertyName())), order);
}
+ protected Ordering orderByNodeDepth( String selectorName ) {
+ return orderByNodeDepth(selectorName, Order.ASCENDING);
+ }
+
+ protected Ordering orderByNodeDepth( String selectorName,
+ Order order ) {
+ return new Ordering(new NodeDepth(selector(selectorName)), order);
+ }
+
+ protected Ordering orderByNodePath( String selectorName ) {
+ return orderByNodePath(selectorName, Order.ASCENDING);
+ }
+
+ protected Ordering orderByNodePath( String selectorName,
+ Order order ) {
+ return new Ordering(new NodePath(selector(selectorName)), order);
+ }
+
protected Ordering orderByNodeName( String selectorName ) {
return orderByNodeName(selectorName, Order.ASCENDING);
}
Modified: trunk/dna-graph/src/test/java/org/jboss/dna/graph/query/process/SortValuesComponentTest.java
===================================================================
--- trunk/dna-graph/src/test/java/org/jboss/dna/graph/query/process/SortValuesComponentTest.java 2009-10-03 04:07:41 UTC (rev 1285)
+++ trunk/dna-graph/src/test/java/org/jboss/dna/graph/query/process/SortValuesComponentTest.java 2009-10-03 04:09:29 UTC (rev 1286)
@@ -33,8 +33,6 @@
import org.jboss.dna.graph.query.QueryResults.Columns;
import org.jboss.dna.graph.query.model.Ordering;
import org.jboss.dna.graph.query.plan.PlanHints;
-import org.jboss.dna.graph.query.process.ProcessingComponent;
-import org.jboss.dna.graph.query.process.SortValuesComponent;
import org.jboss.dna.graph.query.validate.Schemata;
import org.junit.Before;
import org.junit.Test;
@@ -112,8 +110,40 @@
}
@Test
+ public void shouldReturnAllResultsOrderedByNodeDepth() {
+ orderings.add(orderByNodeDepth("Selector1"));
+ component = new SortValuesComponent(delegate, orderings);
+ inputTuples.add(tuple(columns, "/a/b1", "v1", 100, "v4"));
+ inputTuples.add(tuple(columns, "/a/b2/c4", "v4", 100, "v3"));
+ inputTuples.add(tuple(columns, "/a", 100, 100, "v2"));
+ inputTuples.add(tuple(columns, "/a/b4/c3", "v3", 100, "v1"));
+ List<Object[]> expected = new ArrayList<Object[]>();
+ expected.add(inputTuples.get(2));
+ expected.add(inputTuples.get(0));
+ expected.add(inputTuples.get(1));
+ expected.add(inputTuples.get(3));
+ assertThat(component.execute(), is(expected));
+ }
+
+ @Test
+ public void shouldReturnAllResultsOrderedByNodePath() {
+ orderings.add(orderByNodePath("Selector1"));
+ component = new SortValuesComponent(delegate, orderings);
+ inputTuples.add(tuple(columns, "/a/b1", "v1", 100, "v4"));
+ inputTuples.add(tuple(columns, "/a/b1/c4[2]", "v4", 100, "v3"));
+ inputTuples.add(tuple(columns, "/a/b1/c2", 100, 100, "v2"));
+ inputTuples.add(tuple(columns, "/a/b1/c4", "v3", 100, "v1"));
+ List<Object[]> expected = new ArrayList<Object[]>();
+ expected.add(inputTuples.get(0));
+ expected.add(inputTuples.get(2));
+ expected.add(inputTuples.get(3));
+ expected.add(inputTuples.get(1));
+ assertThat(component.execute(), is(expected));
+ }
+
+ @Test
public void shouldReturnAllResultsOrderedByNodeLocalName() {
- orderings.add(orderByNodeName("Selector1"));
+ orderings.add(orderByNodeLocalName("Selector1"));
component = new SortValuesComponent(delegate, orderings);
inputTuples.add(tuple(columns, "/a/b1/c1", "v1", 100, "v4"));
inputTuples.add(tuple(columns, "/a/b2/c4", "v4", 100, "v3"));
Modified: trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/xpath/XPath.java
===================================================================
--- trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/xpath/XPath.java 2009-10-03 04:07:41 UTC (rev 1285)
+++ trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/xpath/XPath.java 2009-10-03 04:09:29 UTC (rev 1286)
@@ -23,13 +23,19 @@
*/
package org.jboss.dna.jcr.xpath;
+import java.util.ArrayList;
+import java.util.Iterator;
import java.util.List;
import org.jboss.dna.common.util.CheckArg;
+import org.jboss.dna.common.util.HashCode;
import org.jboss.dna.common.util.ObjectUtil;
import org.jboss.dna.graph.query.model.Operator;
/**
+ * Abstract syntax components of an XPath query. The supported grammar is defined by JCR 1.0, and is a subset of what is allowed
+ * by the W3C XPath 2.0 specification.
*
+ * @see XPathParser#parseXPath(String)
*/
public class XPath {
@@ -39,10 +45,18 @@
FOLLOWS;
}
- public static interface Component {
+ public static abstract class Component {
+ /**
+ * Return the collapsable form
+ *
+ * @return the collapsed form of th is component; never null and possibly the same as this
+ */
+ public Component collapse() {
+ return this;
+ }
}
- public static abstract class UnaryComponent implements Component {
+ public static abstract class UnaryComponent extends Component {
protected final Component wrapped;
public UnaryComponent( Component wrapped ) {
@@ -85,7 +99,7 @@
}
}
- public static abstract class BinaryComponent implements Component {
+ public static abstract class BinaryComponent extends Component {
private final Component left;
private final Component right;
@@ -121,8 +135,25 @@
}
/**
+ * @return operator
+ */
+ public Operator getOperator() {
+ return operator;
+ }
+
+ /**
* {@inheritDoc}
*
+ * @see org.jboss.dna.jcr.xpath.XPath.Component#collapse()
+ */
+ @Override
+ public Component collapse() {
+ return new Comparison(getLeft().collapse(), operator, getRight().collapse());
+ }
+
+ /**
+ * {@inheritDoc}
+ *
* @see java.lang.Object#toString()
*/
@Override
@@ -160,6 +191,16 @@
/**
* {@inheritDoc}
*
+ * @see org.jboss.dna.jcr.xpath.XPath.Component#collapse()
+ */
+ @Override
+ public Component collapse() {
+ return new NodeComparison(getLeft().collapse(), operator, getRight().collapse());
+ }
+
+ /**
+ * {@inheritDoc}
+ *
* @see java.lang.Object#toString()
*/
@Override
@@ -193,6 +234,16 @@
/**
* {@inheritDoc}
*
+ * @see org.jboss.dna.jcr.xpath.XPath.Component#collapse()
+ */
+ @Override
+ public Component collapse() {
+ return new Add(getLeft().collapse(), getRight().collapse());
+ }
+
+ /**
+ * {@inheritDoc}
+ *
* @see java.lang.Object#toString()
*/
@Override
@@ -225,6 +276,16 @@
/**
* {@inheritDoc}
*
+ * @see org.jboss.dna.jcr.xpath.XPath.Component#collapse()
+ */
+ @Override
+ public Component collapse() {
+ return new Subtract(getLeft().collapse(), getRight().collapse());
+ }
+
+ /**
+ * {@inheritDoc}
+ *
* @see java.lang.Object#toString()
*/
@Override
@@ -257,6 +318,16 @@
/**
* {@inheritDoc}
*
+ * @see org.jboss.dna.jcr.xpath.XPath.Component#collapse()
+ */
+ @Override
+ public Component collapse() {
+ return new And(getLeft().collapse(), getRight().collapse());
+ }
+
+ /**
+ * {@inheritDoc}
+ *
* @see java.lang.Object#toString()
*/
@Override
@@ -312,6 +383,70 @@
}
}
+ public static class Intersect extends BinaryComponent {
+ public Intersect( Component left,
+ Component right ) {
+ super(left, right);
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see java.lang.Object#toString()
+ */
+ @Override
+ public String toString() {
+ return getLeft() + " intersect " + getRight();
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see java.lang.Object#equals(java.lang.Object)
+ */
+ @Override
+ public boolean equals( Object obj ) {
+ if (obj == this) return true;
+ if (obj instanceof Intersect) {
+ Intersect that = (Intersect)obj;
+ return this.getLeft().equals(that.getLeft()) && this.getRight().equals(that.getRight());
+ }
+ return false;
+ }
+ }
+
+ public static class Except extends BinaryComponent {
+ public Except( Component left,
+ Component right ) {
+ super(left, right);
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see java.lang.Object#toString()
+ */
+ @Override
+ public String toString() {
+ return getLeft() + " except " + getRight();
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see java.lang.Object#equals(java.lang.Object)
+ */
+ @Override
+ public boolean equals( Object obj ) {
+ if (obj == this) return true;
+ if (obj instanceof Except) {
+ Except that = (Except)obj;
+ return this.getLeft().equals(that.getLeft()) && this.getRight().equals(that.getRight());
+ }
+ return false;
+ }
+ }
+
public static class Or extends BinaryComponent {
public Or( Component left,
Component right ) {
@@ -321,6 +456,16 @@
/**
* {@inheritDoc}
*
+ * @see org.jboss.dna.jcr.xpath.XPath.Component#collapse()
+ */
+ @Override
+ public Component collapse() {
+ return new Or(getLeft().collapse(), getRight().collapse());
+ }
+
+ /**
+ * {@inheritDoc}
+ *
* @see java.lang.Object#toString()
*/
@Override
@@ -344,7 +489,7 @@
}
}
- public static class ContextItem implements Component {
+ public static class ContextItem extends Component {
/**
* {@inheritDoc}
*
@@ -366,7 +511,7 @@
}
}
- public static class Literal implements Component {
+ public static class Literal extends Component {
private final String value;
public Literal( String value ) {
@@ -380,6 +525,19 @@
return value;
}
+ public boolean isInteger() {
+ try {
+ Integer.parseInt(value);
+ return true;
+ } catch (NumberFormatException e) {
+ return false;
+ }
+ }
+
+ public int getValueAsInteger() {
+ return Integer.parseInt(value);
+ }
+
/**
* {@inheritDoc}
*
@@ -405,7 +563,7 @@
}
}
- public static class FunctionCall implements Component {
+ public static class FunctionCall extends Component {
private final NameTest name;
private final List<Component> arguments;
@@ -434,6 +592,20 @@
/**
* {@inheritDoc}
*
+ * @see org.jboss.dna.jcr.xpath.XPath.Component#collapse()
+ */
+ @Override
+ public Component collapse() {
+ List<Component> args = new ArrayList<Component>(arguments.size());
+ for (Component arg : arguments) {
+ args.add(arg.collapse());
+ }
+ return new FunctionCall(name, args);
+ }
+
+ /**
+ * {@inheritDoc}
+ *
* @see java.lang.Object#equals(java.lang.Object)
*/
@Override
@@ -467,7 +639,7 @@
return sb.toString();
}
- public static class PathExpression implements Component {
+ public static class PathExpression extends Component implements Iterable<StepExpression> {
private final List<StepExpression> steps;
private final boolean relative;
@@ -491,9 +663,37 @@
return steps;
}
+ public StepExpression getLastStep() {
+ return steps.isEmpty() ? null : steps.get(steps.size() - 1);
+ }
+
+ public PathExpression withoutLast() {
+ assert !steps.isEmpty();
+ return new PathExpression(relative, steps.subList(0, steps.size() - 1));
+ }
+
+ public PathExpression withoutFirst() {
+ assert !steps.isEmpty();
+ return new PathExpression(relative, steps.subList(1, steps.size()));
+ }
+
/**
* {@inheritDoc}
*
+ * @see java.lang.Iterable#iterator()
+ */
+ public Iterator<StepExpression> iterator() {
+ return steps.iterator();
+ }
+
+ @Override
+ public Component collapse() {
+ return steps.size() == 1 ? steps.get(0).collapse() : this;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
* @see java.lang.Object#equals(java.lang.Object)
*/
@Override
@@ -517,10 +717,10 @@
}
}
- public static interface StepExpression extends Component {
+ public static abstract class StepExpression extends Component {
}
- public static class FilterStep implements StepExpression {
+ public static class FilterStep extends StepExpression {
private final Component primaryExpression;
private final List<Component> predicates;
@@ -546,6 +746,11 @@
return predicates;
}
+ @Override
+ public Component collapse() {
+ return predicates.isEmpty() ? primaryExpression.collapse() : this;
+ }
+
/**
* {@inheritDoc}
*
@@ -572,7 +777,7 @@
}
}
- public static class DescendantOrSelf implements StepExpression {
+ public static class DescendantOrSelf extends StepExpression {
/**
* {@inheritDoc}
*
@@ -594,7 +799,7 @@
}
}
- public static class AxisStep implements StepExpression {
+ public static class AxisStep extends StepExpression {
private final NodeTest nodeTest;
private final List<Component> predicates;
@@ -620,6 +825,11 @@
return predicates;
}
+ @Override
+ public Component collapse() {
+ return predicates.isEmpty() ? nodeTest.collapse() : this;
+ }
+
/**
* {@inheritDoc}
*
@@ -646,7 +856,7 @@
}
}
- public static class ParenthesizedExpression implements Component {
+ public static class ParenthesizedExpression extends Component {
private final Component wrapped;
public ParenthesizedExpression() {
@@ -667,6 +877,16 @@
/**
* {@inheritDoc}
*
+ * @see org.jboss.dna.jcr.xpath.XPath.Component#collapse()
+ */
+ @Override
+ public Component collapse() {
+ return wrapped instanceof BinaryComponent ? this : wrapped;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
* @see java.lang.Object#equals(java.lang.Object)
*/
@Override
@@ -690,13 +910,13 @@
}
}
- public static interface NodeTest extends Component {
+ public static abstract class NodeTest extends Component {
}
- public static interface KindTest extends NodeTest {
+ public static abstract class KindTest extends NodeTest {
}
- public static class NameTest implements NodeTest {
+ public static class NameTest extends NodeTest {
private final String prefixTest;
private final String localTest;
@@ -707,22 +927,55 @@
}
/**
- * @return prefixTest
+ * @return the prefix criteria, or null if the prefix criteria is a wildcard
*/
public String getPrefixTest() {
return prefixTest;
}
/**
- * @return localTest
+ * @return the local name criteria, or null if the local name criteria is a wildcard
*/
public String getLocalTest() {
return localTest;
}
/**
+ * Determine if this name test exactly matches the supplied prefix and local name values.
+ *
+ * @param prefix the prefix; may be null
+ * @param local the local name; may be null
+ * @return true if this name matches the supplied values, or false otherwise.
+ */
+ public boolean matches( String prefix,
+ String local ) {
+ if (this.prefixTest != null && !this.prefixTest.equals(prefix)) return false;
+ if (this.localTest != null && !this.localTest.equals(local)) return false;
+ return true;
+ }
+
+ /**
+ * Return whether this represents a wildcard, meaning both {@link #getPrefixTest()} and {@link #getLocalTest()} are null.
+ *
+ * @return true if this is a wildcard name test.
+ */
+ public boolean isWildcard() {
+ return prefixTest == null && localTest == null;
+ }
+
+ /**
* {@inheritDoc}
*
+ * @see java.lang.Object#hashCode()
+ */
+ @Override
+ public int hashCode() {
+ return HashCode.compute(this.prefixTest, this.localTest);
+ }
+
+ /**
+ * {@inheritDoc}
+ *
* @see java.lang.Object#equals(java.lang.Object)
*/
@Override
@@ -748,18 +1001,18 @@
}
}
- public static class AttributeNameTest implements NodeTest {
- private final NodeTest nodeTest;
+ public static class AttributeNameTest extends NodeTest {
+ private final NameTest nameTest;
- public AttributeNameTest( NodeTest nodeTest ) {
- this.nodeTest = nodeTest;
+ public AttributeNameTest( NameTest nameTest ) {
+ this.nameTest = nameTest;
}
/**
* @return nodeTest
*/
- public NodeTest getNodeTest() {
- return nodeTest;
+ public NameTest getNameTest() {
+ return nameTest;
}
/**
@@ -769,7 +1022,7 @@
*/
@Override
public String toString() {
- return "@" + nodeTest;
+ return "@" + nameTest;
}
/**
@@ -782,14 +1035,14 @@
if (obj == this) return true;
if (obj instanceof AttributeNameTest) {
AttributeNameTest that = (AttributeNameTest)obj;
- return this.nodeTest.equals(that.nodeTest);
+ return this.nameTest.equals(that.nameTest);
}
return false;
}
}
- public static class AnyKindTest implements KindTest {
+ public static class AnyKindTest extends KindTest {
/**
* {@inheritDoc}
*
@@ -811,7 +1064,7 @@
}
}
- public static class TextTest implements KindTest {
+ public static class TextTest extends KindTest {
/**
* {@inheritDoc}
*
@@ -833,7 +1086,7 @@
}
}
- public static class CommentTest implements KindTest {
+ public static class CommentTest extends KindTest {
/**
* {@inheritDoc}
*
@@ -855,7 +1108,7 @@
}
}
- public static class ProcessingInstructionTest implements KindTest {
+ public static class ProcessingInstructionTest extends KindTest {
private final String nameOrStringLiteral;
public ProcessingInstructionTest( String nameOrStringLiteral ) {
@@ -895,7 +1148,7 @@
}
}
- public static class DocumentTest implements KindTest {
+ public static class DocumentTest extends KindTest {
private KindTest elementOrSchemaElementTest;
public DocumentTest( ElementTest elementTest ) {
@@ -948,7 +1201,7 @@
}
}
- public static class AttributeTest implements KindTest {
+ public static class AttributeTest extends KindTest {
private final NameTest attributeNameOrWildcard;
private final NameTest typeName;
@@ -999,7 +1252,7 @@
}
}
- public static class ElementTest implements KindTest {
+ public static class ElementTest extends KindTest {
private final NameTest elementNameOrWildcard;
private final NameTest typeName;
@@ -1050,7 +1303,7 @@
}
}
- public static class SchemaElementTest implements KindTest {
+ public static class SchemaElementTest extends KindTest {
private final NameTest elementDeclarationName;
public SchemaElementTest( NameTest elementDeclarationName ) {
@@ -1090,7 +1343,7 @@
}
}
- public static class SchemaAttributeTest implements KindTest {
+ public static class SchemaAttributeTest extends KindTest {
private final NameTest attributeDeclarationName;
public SchemaAttributeTest( NameTest attributeDeclarationName ) {
Modified: trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/xpath/XPathParser.java
===================================================================
--- trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/xpath/XPathParser.java 2009-10-03 04:07:41 UTC (rev 1285)
+++ trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/xpath/XPathParser.java 2009-10-03 04:09:29 UTC (rev 1286)
@@ -39,8 +39,6 @@
import org.jboss.dna.graph.property.ValueFactory;
import org.jboss.dna.graph.property.ValueFormatException;
import org.jboss.dna.graph.query.model.Operator;
-import org.jboss.dna.graph.query.model.QueryCommand;
-import org.jboss.dna.graph.query.parse.QueryParser;
import org.jboss.dna.jcr.xpath.XPath.Add;
import org.jboss.dna.jcr.xpath.XPath.And;
import org.jboss.dna.jcr.xpath.XPath.AnyKindTest;
@@ -54,8 +52,10 @@
import org.jboss.dna.jcr.xpath.XPath.DescendantOrSelf;
import org.jboss.dna.jcr.xpath.XPath.DocumentTest;
import org.jboss.dna.jcr.xpath.XPath.ElementTest;
+import org.jboss.dna.jcr.xpath.XPath.Except;
import org.jboss.dna.jcr.xpath.XPath.FilterStep;
import org.jboss.dna.jcr.xpath.XPath.FunctionCall;
+import org.jboss.dna.jcr.xpath.XPath.Intersect;
import org.jboss.dna.jcr.xpath.XPath.KindTest;
import org.jboss.dna.jcr.xpath.XPath.Literal;
import org.jboss.dna.jcr.xpath.XPath.NameTest;
@@ -75,602 +75,606 @@
import org.jboss.dna.jcr.xpath.XPath.Union;
/**
- *
+ * A component that parses an XPath query string and creates an abstract syntax tree representation. The supported grammar is
+ * defined by JCR 1.0, and is a subset of what is allowed by the W3C XPath 2.0 specification.
*/
-public class XPathParser implements QueryParser {
+public class XPathParser {
+ private final ExecutionContext context;
- /**
- * {@inheritDoc}
- *
- * @see org.jboss.dna.graph.query.parse.QueryParser#parseQuery(java.lang.String, org.jboss.dna.graph.ExecutionContext)
- */
- public QueryCommand parseQuery( String query,
- ExecutionContext context ) {
+ public XPathParser( ExecutionContext context ) {
+ this.context = context;
+ }
+
+ public Component parseXPath( String xpath ) {
Tokenizer tokenizer = new XPathTokenizer(false); // skip comments
- TokenStream tokens = new TokenStream(query, tokenizer, true).start(); // case sensitive!!
- Component result = new Parser(context).parseXPath(tokens);
- System.out.println(query);
- System.out.println(" --> " + result);
- return null;
+ TokenStream tokens = new TokenStream(xpath, tokenizer, true).start(); // case sensitive!!
+ return parseXPath(tokens);
}
- protected static class Parser {
- private final ExecutionContext context;
+ protected Component parseXPath( TokenStream tokens ) {
+ return parseExpr(tokens);
+ }
- protected Parser( ExecutionContext context ) {
- this.context = context;
+ protected Component parseExpr( TokenStream tokens ) {
+ Component result = parseExprSingle(tokens);
+ if (tokens.matches(',')) {
+ throw new ParsingException(tokens.nextPosition(), "Multiple XPath expressions are not supported");
}
+ return result;
+ }
- protected Component parseXPath( TokenStream tokens ) {
- return parseExpr(tokens);
+ protected Component parseExprSingle( TokenStream tokens ) {
+ if (tokens.matches("for", "$", ANY_VALUE, "IN")) {
+ throw new ParsingException(tokens.nextPosition(), "XPath 'for' expressions are not supported");
}
+ if (tokens.matches("some", "$", ANY_VALUE, "IN")) {
+ throw new ParsingException(tokens.nextPosition(), "XPath 'some' expressions are not supported");
+ }
+ if (tokens.matches("every", "$", ANY_VALUE, "IN")) {
+ throw new ParsingException(tokens.nextPosition(), "XPath 'every' expressions are not supported");
+ }
+ if (tokens.matches("if", "(", ANY_VALUE, "IN")) {
+ throw new ParsingException(tokens.nextPosition(), "XPath if-then-else expressions are not supported");
+ }
+ return parseOrExpr(tokens);
+ }
- protected Component parseExpr( TokenStream tokens ) {
- Component result = parseExprSingle(tokens);
- if (tokens.matches(',')) {
- throw new ParsingException(tokens.nextPosition(), "Multiple XPath expressions are not supported");
- }
- return result;
+ protected Component parseOrExpr( TokenStream tokens ) {
+ Component result = parseAndExpr(tokens);
+ while (tokens.canConsume("or")) {
+ result = new Or(result, parseInstanceofExpr(tokens));
}
+ return result;
+ }
- protected Component parseExprSingle( TokenStream tokens ) {
- if (tokens.matches("for", "$", ANY_VALUE, "IN")) {
- throw new ParsingException(tokens.nextPosition(), "XPath 'for' expressions are not supported");
- }
- if (tokens.matches("some", "$", ANY_VALUE, "IN")) {
- throw new ParsingException(tokens.nextPosition(), "XPath 'some' expressions are not supported");
- }
- if (tokens.matches("every", "$", ANY_VALUE, "IN")) {
- throw new ParsingException(tokens.nextPosition(), "XPath 'every' expressions are not supported");
- }
- if (tokens.matches("if", "(", ANY_VALUE, "IN")) {
- throw new ParsingException(tokens.nextPosition(), "XPath if-then-else expressions are not supported");
- }
- return parseOrExpr(tokens);
+ protected Component parseAndExpr( TokenStream tokens ) {
+ Component result = parseInstanceofExpr(tokens);
+ while (tokens.canConsume("and")) {
+ result = new And(result, parseInstanceofExpr(tokens));
}
+ return result;
+ }
- protected Component parseOrExpr( TokenStream tokens ) {
- Component result = parseAndExpr(tokens);
- while (tokens.canConsume("or")) {
- result = new Or(result, parseInstanceofExpr(tokens));
- }
- return result;
+ protected Component parseInstanceofExpr( TokenStream tokens ) {
+ Component result = parseTreatExpr(tokens);
+ if (tokens.matches("instance", "of")) {
+ throw new ParsingException(tokens.nextPosition(), "XPath 'instance of' expressions are not supported");
}
+ return result;
+ }
- protected Component parseAndExpr( TokenStream tokens ) {
- Component result = parseInstanceofExpr(tokens);
- while (tokens.canConsume("and")) {
- result = new And(result, parseInstanceofExpr(tokens));
- }
- return result;
+ protected Component parseTreatExpr( TokenStream tokens ) {
+ Component result = parseCastableExpr(tokens);
+ if (tokens.matches("treat", "as")) {
+ throw new ParsingException(tokens.nextPosition(), "XPath 'treat as' expressions are not supported");
}
+ return result;
+ }
- protected Component parseInstanceofExpr( TokenStream tokens ) {
- Component result = parseTreatExpr(tokens);
- if (tokens.matches("instance", "of")) {
- throw new ParsingException(tokens.nextPosition(), "XPath 'instance of' expressions are not supported");
- }
- return result;
+ protected Component parseCastableExpr( TokenStream tokens ) {
+ Component result = parseCastExpr(tokens);
+ if (tokens.matches("castable", "as")) {
+ throw new ParsingException(tokens.nextPosition(), "XPath 'castable as' expressions are not supported");
}
+ return result;
+ }
- protected Component parseTreatExpr( TokenStream tokens ) {
- Component result = parseCastableExpr(tokens);
- if (tokens.matches("treat", "as")) {
- throw new ParsingException(tokens.nextPosition(), "XPath 'treat as' expressions are not supported");
- }
- return result;
+ protected Component parseCastExpr( TokenStream tokens ) {
+ Component result = parseComparisonExpr(tokens);
+ if (tokens.matches("cast", "as")) {
+ throw new ParsingException(tokens.nextPosition(), "XPath 'cast as' expressions are not supported");
}
+ return result;
+ }
- protected Component parseCastableExpr( TokenStream tokens ) {
- Component result = parseCastExpr(tokens);
- if (tokens.matches("castable", "as")) {
- throw new ParsingException(tokens.nextPosition(), "XPath 'castable as' expressions are not supported");
- }
- return result;
+ protected Component parseComparisonExpr( TokenStream tokens ) {
+ Component result = parseRangeExpr(tokens);
+ // General comparison is optional ...
+ Operator operator = parseGeneralComp(tokens);
+ if (operator == null) parseValueComp(tokens);
+ if (operator != null) {
+ return new Comparison(result, operator, parseRangeExpr(tokens));
}
+ NodeComparisonOperator nodeComp = parseNodeComp(tokens);
+ if (nodeComp != null) {
+ return new NodeComparison(result, nodeComp, parseRangeExpr(tokens));
+ }
+ return result;
+ }
- protected Component parseCastExpr( TokenStream tokens ) {
- Component result = parseComparisonExpr(tokens);
- if (tokens.matches("cast", "as")) {
- throw new ParsingException(tokens.nextPosition(), "XPath 'cast as' expressions are not supported");
- }
- return result;
+ protected Component parseValueComp( TokenStream tokens ) {
+ if (tokens.matchesAnyOf("eq", "ne", "lt", "le", "gt")) {
+ throw new ParsingException(tokens.nextPosition(),
+ "XPath value comparisons using 'eq', 'ne', 'lt', 'le', or 'gt' are not supported");
}
+ return null;
+ }
- protected Component parseComparisonExpr( TokenStream tokens ) {
- Component result = parseRangeExpr(tokens);
- // General comparison is optional ...
- Operator operator = parseGeneralComp(tokens);
- if (operator == null) parseValueComp(tokens);
- if (operator != null) {
- return new Comparison(result, operator, parseRangeExpr(tokens));
- }
- NodeComparisonOperator nodeComp = parseNodeComp(tokens);
- if (nodeComp != null) {
- return new NodeComparison(result, nodeComp, parseRangeExpr(tokens));
- }
- return result;
+ protected NodeComparisonOperator parseNodeComp( TokenStream tokens ) {
+ if (tokens.matches("is") || tokens.matches("<", "<") || tokens.matches(">", ">")) {
+ throw new ParsingException(tokens.nextPosition(), "XPath 'is', '<<' and '>>' expressions are not supported");
}
+ return null;
+ }
- protected Component parseValueComp( TokenStream tokens ) {
- if (tokens.matchesAnyOf("eq", "ne", "lt", "le", "gt")) {
- throw new ParsingException(tokens.nextPosition(),
- "XPath value comparisons using 'eq', 'ne', 'lt', 'le', or 'gt' are not supported");
- }
- return null;
+ protected Component parseRangeExpr( TokenStream tokens ) {
+ Component result = parseAdditiveExpr(tokens);
+ if (tokens.matches("to")) {
+ throw new ParsingException(tokens.nextPosition(), "XPath range expressions with 'to' are not supported");
}
+ return result;
+ }
- protected NodeComparisonOperator parseNodeComp( TokenStream tokens ) {
- if (tokens.matches("is") || tokens.matches("<", "<") || tokens.matches(">", ">")) {
- throw new ParsingException(tokens.nextPosition(), "XPath 'is', '<<' and '>>' expressions are not supported");
+ protected Component parseAdditiveExpr( TokenStream tokens ) {
+ Component result = parseMultiplicativeExpr(tokens);
+ while (true) {
+ if (tokens.canConsume("+")) {
+ result = new Add(result, parseMultiplicativeExpr(tokens));
+ } else if (tokens.canConsume("-")) {
+ result = new Subtract(result, parseMultiplicativeExpr(tokens));
+ } else {
+ break; // no more additions
}
- return null;
}
+ return result;
+ }
- protected Component parseRangeExpr( TokenStream tokens ) {
- Component result = parseAdditiveExpr(tokens);
- if (tokens.matches("to")) {
- throw new ParsingException(tokens.nextPosition(), "XPath range expressions with 'to' are not supported");
- }
- return result;
+ protected Component parseMultiplicativeExpr( TokenStream tokens ) {
+ Component result = parseUnaryExpr(tokens);
+ if (tokens.matchesAnyOf("+", "div", "idiv", "mod")) {
+ throw new ParsingException(tokens.nextPosition(),
+ "XPath multiplicative expressions using '+', 'div', 'idiv', or 'mod' are not supported");
}
+ return result;
+ }
- protected Component parseAdditiveExpr( TokenStream tokens ) {
- Component result = parseMultiplicativeExpr(tokens);
- while (true) {
- if (tokens.canConsume("+")) {
- result = new Add(result, parseMultiplicativeExpr(tokens));
- } else if (tokens.canConsume("-")) {
- result = new Subtract(result, parseMultiplicativeExpr(tokens));
- } else {
- break; // no more additions
- }
- }
- return result;
+ protected Component parseUnaryExpr( TokenStream tokens ) {
+ boolean negative = false;
+ // Technically more than one +/- are allowed by the spec
+ while (tokens.matchesAnyOf("+", "-")) {
+ if (tokens.canConsume("-")) negative = true;
+ tokens.canConsume("+");
}
+ Component result = parseUnionExpr(tokens);
+ return negative ? new Negation(result) : result;
+ }
- protected Component parseMultiplicativeExpr( TokenStream tokens ) {
- Component result = parseUnaryExpr(tokens);
- if (tokens.matchesAnyOf("+", "div", "idiv", "mod")) {
- throw new ParsingException(tokens.nextPosition(),
- "XPath multiplicative expressions using '+', 'div', 'idiv', or 'mod' are not supported");
+ protected Component parseUnionExpr( TokenStream tokens ) {
+ Component result = parseIntersectExceptExpr(tokens);
+ while (true) {
+ if (tokens.canConsumeAnyOf("union", "|")) {
+ result = new Union(result, parseIntersectExceptExpr(tokens));
+ } else {
+ break; // no more
}
- return result;
}
+ return result;
+ }
- protected Component parseUnaryExpr( TokenStream tokens ) {
- boolean negative = false;
- // Technically more than one +/- are allowed by the spec
- while (tokens.matchesAnyOf("+", "-")) {
- if (tokens.canConsume("-")) negative = true;
- tokens.canConsume("+");
+ protected Component parseIntersectExceptExpr( TokenStream tokens ) {
+ Component result = parseValueExpr(tokens);
+ while (true) {
+ if (tokens.canConsumeAnyOf("intersect")) {
+ result = new Intersect(result, parseValueExpr(tokens));
+ } else if (tokens.canConsumeAnyOf("except")) {
+ result = new Except(result, parseValueExpr(tokens));
+ } else {
+ break; // no more
}
- Component result = parseUnionExpr(tokens);
- return negative ? new Negation(result) : result;
}
+ return result;
+ }
- protected Component parseUnionExpr( TokenStream tokens ) {
- Component result = parseIntersectExceptExpr(tokens);
- while (true) {
- if (tokens.canConsumeAnyOf("union", "|")) {
- result = new Union(result, parseIntersectExceptExpr(tokens));
- } else {
- break; // no more
+ protected Component parseValueExpr( TokenStream tokens ) {
+ return parsePathExpr(tokens);
+ }
+
+ protected PathExpression parsePathExpr( TokenStream tokens ) {
+ boolean relative = true;
+ boolean prependDependentOrSelf = false;
+ if (tokens.canConsume('/')) {
+ if (tokens.canConsume('/')) {
+ if (!tokens.hasNext()) {
+ // See http://www.w3.org/XML/2007/qt-errata/xpath20-errata.html#E3
+ throw new ParsingException(tokens.previousPosition(), "'//' is not a valid XPath expression");
}
+ prependDependentOrSelf = true;
}
- return result;
+ relative = false;
}
-
- protected Component parseIntersectExceptExpr( TokenStream tokens ) {
- Component result = parseValueExpr(tokens);
- if (tokens.matchesAnyOf("intersect", "except")) {
- throw new ParsingException(tokens.nextPosition(),
- "XPath multiplicative expressions using '+', 'div', 'idiv', or 'mod' are not supported");
- }
- return result;
+ PathExpression result = new PathExpression(relative, parseRelativePathExpr(tokens).getSteps());
+ if (prependDependentOrSelf) {
+ result.getSteps().add(0, new DescendantOrSelf());
}
+ return result;
+ }
- protected Component parseValueExpr( TokenStream tokens ) {
- return parsePathExpr(tokens);
- }
-
- protected PathExpression parsePathExpr( TokenStream tokens ) {
- boolean relative = true;
- boolean prependDependentOrSelf = false;
+ protected PathExpression parseRelativePathExpr( TokenStream tokens ) {
+ List<StepExpression> steps = new ArrayList<StepExpression>();
+ steps.add(parseStepExpr(tokens));
+ while (tokens.canConsume('/')) {
if (tokens.canConsume('/')) {
- if (tokens.canConsume('/')) {
- if (!tokens.hasNext()) {
- // See http://www.w3.org/XML/2007/qt-errata/xpath20-errata.html#E3
- throw new ParsingException(tokens.previousPosition(), "'//' is not a valid XPath expression");
- }
- prependDependentOrSelf = true;
- }
- relative = false;
+ steps.add(new DescendantOrSelf());
}
- PathExpression result = new PathExpression(relative, parseRelativePathExpr(tokens).getSteps());
- if (prependDependentOrSelf) {
- result.getSteps().add(0, new DescendantOrSelf());
+ if (tokens.hasNext()) {
+ steps.add(parseStepExpr(tokens));
}
- return result;
}
+ return new PathExpression(true, steps);
+ }
- protected PathExpression parseRelativePathExpr( TokenStream tokens ) {
- List<StepExpression> steps = new ArrayList<StepExpression>();
- steps.add(parseStepExpr(tokens));
- while (tokens.canConsume('/')) {
- if (tokens.canConsume('/')) {
- steps.add(new DescendantOrSelf());
- }
- if (tokens.hasNext()) {
- steps.add(parseStepExpr(tokens));
- }
- }
- return new PathExpression(true, steps);
+ protected StepExpression parseStepExpr( TokenStream tokens ) {
+ KindTest kindTest = parseKindTest(tokens);
+ if (kindTest != null) {
+ // Now parse the predicates ...
+ List<Component> predicates = parsePredicates(tokens);
+ return new AxisStep(kindTest, predicates);
}
-
- protected StepExpression parseStepExpr( TokenStream tokens ) {
- if (tokens.matches('(') || tokens.matches('.') || tokens.matches(XPathTokenizer.QUOTED_STRING)
- || tokens.matches(ANY_VALUE, "(") || tokens.matches(ANY_VALUE, ":", ANY_VALUE, "(")) {
- // We know its a filter expression (though literals don't fit this pattern) ...
- return parseFilterExpr(tokens);
- }
- AxisStep result = parseAxisStep(tokens);
- if (result != null) return result;
- // It must be the remaining kind of filter expression ...
+ if (tokens.matches('(') || tokens.matches('.') || tokens.matches(XPathTokenizer.QUOTED_STRING)
+ || tokens.matches(ANY_VALUE, "(") || tokens.matches(ANY_VALUE, ":", ANY_VALUE, "(")) {
+ // We know its a filter expression (though literals don't fit this pattern) ...
return parseFilterExpr(tokens);
}
+ AxisStep result = parseAxisStep(tokens);
+ if (result != null) return result;
+ // It must be the remaining kind of filter expression ...
+ return parseFilterExpr(tokens);
+ }
- protected AxisStep parseAxisStep( TokenStream tokens ) {
- NodeTest nodeTest = null;
- if (tokens.canConsume('@')) {
- // Abbreviated forward step with an attribute...
- nodeTest = new AttributeNameTest(parseNodeTest(tokens));
- } else if (tokens.matches('*')) {
- // Abbreviated forward step with an wildcard element ...
- nodeTest = parseNodeTest(tokens);
+ protected AxisStep parseAxisStep( TokenStream tokens ) {
+ NodeTest nodeTest = null;
+ if (tokens.canConsume('@')) {
+ // Abbreviated forward step with an attribute...
+ nodeTest = new AttributeNameTest(parseNameTest(tokens));
+ } else if (tokens.matches('*')) {
+ // Abbreviated forward step with an wildcard element ...
+ nodeTest = parseNodeTest(tokens);
- } else if (tokens.matches("child", ":", ":") || tokens.matches("attribute", ":", ":")
- || tokens.matches("self", ":", ":") || tokens.matches("descendant", ":", ":")
- || tokens.matches("descendant-or-self", ":", ":") || tokens.matches("following-sibling", ":", ":")
- || tokens.matches("following", ":", ":") || tokens.matches("namespace", ":", ":")) {
- // No non-abbreviated forward steps allowed
- throw new ParsingException(
- tokens.nextPosition(),
- "XPath non-abbreviated forward steps (e.g., 'child::', 'attribute::', 'self::', 'descendant::', 'descendant-or-self::', 'following-sibling::', 'following::', or 'namespace::') are not supported");
- } else if (tokens.matches("..")) {
- // No abbreviated reverse steps allowed ...
- throw new ParsingException(tokens.nextPosition(),
- "XPath abbreviated reverse steps (e.g., '..') are not supported");
- } else if (tokens.matches("parent", ":", ":") || tokens.matches("ancestor-or-self", ":", ":")
- || tokens.matches("preceding-sibling", ":", ":") || tokens.matches("preceding", ":", ":")
- || tokens.matches("ancestor", ":", ":")) {
- // No non-abbreviated reverse steps allowed ...
- throw new ParsingException(
- tokens.nextPosition(),
- "XPath non-abbreviated reverse steps (e.g., 'parent::', 'ancestor::', 'ancestor-or-self::', 'preceding-or-sibling::', or 'preceding::') are not supported");
- } else if (tokens.matches(ANY_VALUE, ":", ANY_VALUE)
- && tokens.matches(XPathTokenizer.NAME, XPathTokenizer.SYMBOL, XPathTokenizer.NAME)) {
- // This is probably a forward step with a (qualified) name test ...
- nodeTest = parseQName(tokens);
- } else if (tokens.matches(XPathTokenizer.NAME)) {
- // This is probably a forward step with an unqualified name test ...
- nodeTest = parseNodeTest(tokens);
- } else {
- return null;
- }
-
- // Parse the predicates
- List<Component> predicates = parsePredicates(tokens);
- return new AxisStep(nodeTest, predicates);
+ } else if (tokens.matches("child", ":", ":") || tokens.matches("attribute", ":", ":") || tokens.matches("self", ":", ":")
+ || tokens.matches("descendant", ":", ":") || tokens.matches("descendant-or-self", ":", ":")
+ || tokens.matches("following-sibling", ":", ":") || tokens.matches("following", ":", ":")
+ || tokens.matches("namespace", ":", ":")) {
+ // No non-abbreviated forward steps allowed
+ throw new ParsingException(
+ tokens.nextPosition(),
+ "XPath non-abbreviated forward steps (e.g., 'child::', 'attribute::', 'self::', 'descendant::', 'descendant-or-self::', 'following-sibling::', 'following::', or 'namespace::') are not supported");
+ } else if (tokens.matches("..")) {
+ // No abbreviated reverse steps allowed ...
+ throw new ParsingException(tokens.nextPosition(), "XPath abbreviated reverse steps (e.g., '..') are not supported");
+ } else if (tokens.matches("parent", ":", ":") || tokens.matches("ancestor-or-self", ":", ":")
+ || tokens.matches("preceding-sibling", ":", ":") || tokens.matches("preceding", ":", ":")
+ || tokens.matches("ancestor", ":", ":")) {
+ // No non-abbreviated reverse steps allowed ...
+ throw new ParsingException(
+ tokens.nextPosition(),
+ "XPath non-abbreviated reverse steps (e.g., 'parent::', 'ancestor::', 'ancestor-or-self::', 'preceding-or-sibling::', or 'preceding::') are not supported");
+ } else if (tokens.matches(ANY_VALUE, ":", ANY_VALUE)
+ && tokens.matches(XPathTokenizer.NAME, XPathTokenizer.SYMBOL, XPathTokenizer.NAME)) {
+ // This is probably a forward step with a (qualified) name test ...
+ nodeTest = parseQName(tokens);
+ } else if (tokens.matches(XPathTokenizer.NAME)) {
+ // This is probably a forward step with an unqualified name test ...
+ nodeTest = parseNodeTest(tokens);
+ } else {
+ return null;
}
- protected List<Component> parsePredicates( TokenStream tokens ) {
- List<Component> predicates = new ArrayList<Component>();
- while (tokens.canConsume('[')) {
- predicates.add(parseExpr(tokens));
- tokens.consume(']');
- }
- return predicates;
- }
+ // Parse the predicates
+ List<Component> predicates = parsePredicates(tokens);
+ return new AxisStep(nodeTest, predicates);
+ }
- protected FilterStep parseFilterExpr( TokenStream tokens ) {
- Component primaryExpr = parsePrimaryExpr(tokens);
- List<Component> predicates = parsePredicates(tokens);
- return new FilterStep(primaryExpr, predicates);
+ protected List<Component> parsePredicates( TokenStream tokens ) {
+ List<Component> predicates = new ArrayList<Component>();
+ while (tokens.canConsume('[')) {
+ predicates.add(collapse(parseExpr(tokens)));
+ tokens.consume(']');
}
+ return predicates;
+ }
- protected Component parsePrimaryExpr( TokenStream tokens ) {
- if (tokens.matches('(')) {
- return parseParenthesizedExpr(tokens);
- }
- if (tokens.matches('.')) {
- return parseContextItemExpr(tokens);
- }
- if (tokens.matches(XPathTokenizer.QUOTED_STRING)) {
- return parseStringLiteral(tokens);
- }
- if (tokens.matches(ANY_VALUE, "(") || tokens.matches(ANY_VALUE, ":", ANY_VALUE, "(")) {
- return parseFunctionCall(tokens);
- }
- return parseNumericLiteral(tokens);
- }
+ protected FilterStep parseFilterExpr( TokenStream tokens ) {
+ Component primaryExpr = parsePrimaryExpr(tokens);
+ List<Component> predicates = parsePredicates(tokens);
+ return new FilterStep(primaryExpr, predicates);
+ }
- protected ContextItem parseContextItemExpr( TokenStream tokens ) {
- tokens.consume('.');
- return new ContextItem();
+ protected Component parsePrimaryExpr( TokenStream tokens ) {
+ if (tokens.matches('(')) {
+ return parseParenthesizedExpr(tokens);
}
+ if (tokens.matches('.')) {
+ return parseContextItemExpr(tokens);
+ }
+ if (tokens.matches(XPathTokenizer.QUOTED_STRING)) {
+ return parseStringLiteral(tokens);
+ }
+ if (tokens.matches(ANY_VALUE, "(") || tokens.matches(ANY_VALUE, ":", ANY_VALUE, "(")) {
+ return parseFunctionCall(tokens);
+ }
+ return parseNumericLiteral(tokens);
+ }
- protected ParenthesizedExpression parseParenthesizedExpr( TokenStream tokens ) {
- tokens.consume('(');
- if (tokens.canConsume(')')) {
- return new ParenthesizedExpression();
- }
- Component expr = parseExpr(tokens);
- tokens.consume(')');
- return new ParenthesizedExpression(expr);
+ protected ContextItem parseContextItemExpr( TokenStream tokens ) {
+ tokens.consume('.');
+ return new ContextItem();
+ }
+
+ protected ParenthesizedExpression parseParenthesizedExpr( TokenStream tokens ) {
+ tokens.consume('(');
+ if (tokens.canConsume(')')) {
+ return new ParenthesizedExpression();
}
+ Component expr = collapse(parseExpr(tokens));
+ tokens.consume(')');
+ return new ParenthesizedExpression(expr);
+ }
- protected Literal parseNumericLiteral( TokenStream tokens ) {
- Position pos = tokens.nextPosition();
- String sign = "";
- if (tokens.canConsume('-')) sign = "-";
- else if (tokens.canConsume('+')) sign = "";
+ protected Literal parseNumericLiteral( TokenStream tokens ) {
+ Position pos = tokens.nextPosition();
+ String sign = "";
+ if (tokens.canConsume('-')) sign = "-";
+ else if (tokens.canConsume('+')) sign = "";
- // Try to parse this value as a number ...
- ValueFactory<String> stringFactory = context.getValueFactories().getStringFactory();
- String number = tokens.consume();
- if (number.indexOf(".") != -1) {
- String value = sign + number;
- if (value.endsWith("e") && (tokens.matches('+') || tokens.matches('-'))) {
- // There's more to the number ...
- value = value + tokens.consume() + tokens.consume(); // +/-EXP
- }
- try {
- // Convert to a double and then back to a string to get canonical form ...
- String canonical = stringFactory.create(context.getValueFactories().getDoubleFactory().create(value));
- return new Literal(canonical);
- } catch (ValueFormatException e) {
- String msg = GraphI18n.expectingLiteralAndUnableToParseAsDouble.text(value, pos.getLine(), pos.getColumn());
- throw new ParsingException(pos, msg);
- }
+ // Try to parse this value as a number ...
+ ValueFactory<String> stringFactory = context.getValueFactories().getStringFactory();
+ String number = tokens.consume();
+ if (number.indexOf(".") != -1) {
+ String value = sign + number;
+ if (value.endsWith("e") && (tokens.matches('+') || tokens.matches('-'))) {
+ // There's more to the number ...
+ value = value + tokens.consume() + tokens.consume(); // +/-EXP
}
- // try to parse an a long ...
- String value = sign + number;
try {
- // Convert to a long and then back to a string to get canonical form ...
- String canonical = stringFactory.create(context.getValueFactories().getLongFactory().create(value));
+ // Convert to a double and then back to a string to get canonical form ...
+ String canonical = stringFactory.create(context.getValueFactories().getDoubleFactory().create(value));
return new Literal(canonical);
} catch (ValueFormatException e) {
- String msg = GraphI18n.expectingLiteralAndUnableToParseAsLong.text(value, pos.getLine(), pos.getColumn());
+ String msg = GraphI18n.expectingLiteralAndUnableToParseAsDouble.text(value, pos.getLine(), pos.getColumn());
throw new ParsingException(pos, msg);
}
}
-
- protected Literal parseStringLiteral( TokenStream tokens ) {
- boolean removeQuotes = tokens.matches(XPathTokenizer.QUOTED_STRING);
- String value = tokens.consume();
- if (removeQuotes) value = removeQuotes(value);
- return new Literal(value);
+ // try to parse an a long ...
+ String value = sign + number;
+ try {
+ // Convert to a long and then back to a string to get canonical form ...
+ String canonical = stringFactory.create(context.getValueFactories().getLongFactory().create(value));
+ return new Literal(canonical);
+ } catch (ValueFormatException e) {
+ String msg = GraphI18n.expectingLiteralAndUnableToParseAsLong.text(value, pos.getLine(), pos.getColumn());
+ throw new ParsingException(pos, msg);
}
+ }
- protected FunctionCall parseFunctionCall( TokenStream tokens ) {
- NameTest name = parseQName(tokens);
- tokens.consume("(");
- List<Component> args = new ArrayList<Component>();
- if (!tokens.matches(')')) {
- do {
- args.add(parseExprSingle(tokens));
- } while (tokens.canConsume(","));
- tokens.consume(")");
- }
- return new FunctionCall(name, args);
- }
+ protected Literal parseStringLiteral( TokenStream tokens ) {
+ boolean removeQuotes = tokens.matches(XPathTokenizer.QUOTED_STRING);
+ String value = tokens.consume();
+ if (removeQuotes) value = removeQuotes(value);
+ return new Literal(value);
+ }
- protected Operator parseGeneralComp( TokenStream tokens ) {
- if (tokens.canConsume("!", "=")) return Operator.NOT_EQUAL_TO;
- if (tokens.canConsume("=")) return Operator.EQUAL_TO;
- if (tokens.canConsume("<", "=")) return Operator.LESS_THAN_OR_EQUAL_TO;
- if (tokens.canConsume(">", "=")) return Operator.GREATER_THAN_OR_EQUAL_TO;
- if (tokens.canConsume("<")) return Operator.LESS_THAN;
- if (tokens.canConsume(">")) return Operator.GREATER_THAN;
- return null;
+ protected FunctionCall parseFunctionCall( TokenStream tokens ) {
+ NameTest name = parseQName(tokens);
+ tokens.consume("(");
+ List<Component> args = new ArrayList<Component>();
+ if (!tokens.matches(')')) {
+ do {
+ args.add(collapse(parseExprSingle(tokens)));
+ } while (tokens.canConsume(","));
+ tokens.consume(")");
}
+ return new FunctionCall(name, args);
+ }
- protected NodeTest parseNodeTest( TokenStream tokens ) {
- KindTest kind = parseKindTest(tokens);
- if (kind != null) return kind;
- return parseNameTest(tokens);
- }
+ protected Operator parseGeneralComp( TokenStream tokens ) {
+ if (tokens.canConsume("!", "=")) return Operator.NOT_EQUAL_TO;
+ if (tokens.canConsume("=")) return Operator.EQUAL_TO;
+ if (tokens.canConsume("<", "=")) return Operator.LESS_THAN_OR_EQUAL_TO;
+ if (tokens.canConsume(">", "=")) return Operator.GREATER_THAN_OR_EQUAL_TO;
+ if (tokens.canConsume("<")) return Operator.LESS_THAN;
+ if (tokens.canConsume(">")) return Operator.GREATER_THAN;
+ return null;
+ }
- protected NameTest parseNameTest( TokenStream tokens ) {
- NameTest wildcard = parseWildcard(tokens);
- if (wildcard != null) return wildcard;
- return parseQName(tokens);
- }
+ protected NodeTest parseNodeTest( TokenStream tokens ) {
+ KindTest kind = parseKindTest(tokens);
+ if (kind != null) return kind;
+ return parseNameTest(tokens);
+ }
- protected NameTest parseQName( TokenStream tokens ) {
- String firstPart = parseNCName(tokens);
- if (tokens.canConsume(':')) {
- String secondPart = tokens.consume();
- return new NameTest(firstPart, secondPart);
- }
- return new NameTest(null, firstPart);
+ protected NameTest parseNameTest( TokenStream tokens ) {
+ NameTest wildcard = parseWildcard(tokens);
+ if (wildcard != null) return wildcard;
+ return parseQName(tokens);
+ }
+
+ protected NameTest parseQName( TokenStream tokens ) {
+ String firstPart = parseNCName(tokens);
+ if (tokens.canConsume(':')) {
+ String secondPart = tokens.consume();
+ return new NameTest(firstPart, secondPart);
}
+ return new NameTest(null, firstPart);
+ }
- protected String parseNCName( TokenStream tokens ) {
- String name = tokens.consume();
- if (!XmlCharacters.isValidNcName(name)) {
- throw new ParsingException(tokens.previousPosition(), "Expected valid NCName but found " + name);
- }
- return name;
+ protected String parseNCName( TokenStream tokens ) {
+ String name = tokens.consume();
+ if (!XmlCharacters.isValidNcName(name)) {
+ throw new ParsingException(tokens.previousPosition(), "Expected valid NCName but found " + name);
}
+ return name;
+ }
- protected NameTest parseWildcard( TokenStream tokens ) {
- if (tokens.canConsume('*')) {
- if (tokens.canConsume(':')) {
- if (tokens.canConsume('*')) {
- return new NameTest(null, null);
- }
- String localName = tokens.consume();
- return new NameTest(null, localName);
+ protected NameTest parseWildcard( TokenStream tokens ) {
+ if (tokens.canConsume('*')) {
+ if (tokens.canConsume(':')) {
+ if (tokens.canConsume('*')) {
+ return new NameTest(null, null);
}
- return new NameTest(null, null);
+ String localName = tokens.consume();
+ return new NameTest(null, localName);
}
- if (tokens.matches(XPathTokenizer.NAME, XPathTokenizer.SYMBOL, XPathTokenizer.SYMBOL)
- && tokens.matches(TokenStream.ANY_VALUE, ":", "*")) {
- String prefix = tokens.consume();
- tokens.consume(':');
- tokens.consume('*');
- return new NameTest(prefix, null);
- }
- return null;
+ return new NameTest(null, null);
}
-
- protected NameTest parseItemType( TokenStream tokens ) {
- return parseQName(tokens);
+ if (tokens.matches(XPathTokenizer.NAME, XPathTokenizer.SYMBOL, XPathTokenizer.SYMBOL)
+ && tokens.matches(TokenStream.ANY_VALUE, ":", "*")) {
+ String prefix = tokens.consume();
+ tokens.consume(':');
+ tokens.consume('*');
+ return new NameTest(prefix, null);
}
+ return null;
+ }
- protected NameTest parseAtomicType( TokenStream tokens ) {
- return parseQName(tokens);
- }
+ protected NameTest parseItemType( TokenStream tokens ) {
+ return parseQName(tokens);
+ }
- protected KindTest parseKindTest( TokenStream tokens ) {
- KindTest result = parseAnyKindTest(tokens);
- if (result == null) result = parseDocumentTest(tokens);
- if (result == null) result = parseElementTest(tokens);
- if (result == null) result = parseAttributeTest(tokens);
- if (result == null) result = parseSchemaElementTest(tokens);
- if (result == null) result = parseSchemaAttributeTest(tokens);
- if (result == null) result = parsePITest(tokens);
- if (result == null) result = parseCommentTest(tokens);
- if (result == null) result = parseTextTest(tokens);
- return result;
- }
+ protected NameTest parseAtomicType( TokenStream tokens ) {
+ return parseQName(tokens);
+ }
- protected AnyKindTest parseAnyKindTest( TokenStream tokens ) {
- if (tokens.canConsume("node", "(", ")")) {
- return new AnyKindTest();
- }
- return null;
- }
+ protected KindTest parseKindTest( TokenStream tokens ) {
+ KindTest result = parseAnyKindTest(tokens);
+ if (result == null) result = parseDocumentTest(tokens);
+ if (result == null) result = parseElementTest(tokens);
+ if (result == null) result = parseAttributeTest(tokens);
+ if (result == null) result = parseSchemaElementTest(tokens);
+ if (result == null) result = parseSchemaAttributeTest(tokens);
+ if (result == null) result = parsePITest(tokens);
+ if (result == null) result = parseCommentTest(tokens);
+ if (result == null) result = parseTextTest(tokens);
+ return result;
+ }
- protected ProcessingInstructionTest parsePITest( TokenStream tokens ) {
- if (tokens.canConsume("processing-instruction", "(")) {
- if (tokens.canConsume(")")) return new ProcessingInstructionTest(null);
- String nameOrStringLiteral = tokens.consume();
- tokens.consume(")");
- return new ProcessingInstructionTest(nameOrStringLiteral);
- }
- return null;
+ protected AnyKindTest parseAnyKindTest( TokenStream tokens ) {
+ if (tokens.canConsume("node", "(", ")")) {
+ return new AnyKindTest();
}
+ return null;
+ }
- protected CommentTest parseCommentTest( TokenStream tokens ) {
- if (tokens.canConsume("comment", "(", ")")) {
- return new CommentTest();
- }
- return null;
+ protected ProcessingInstructionTest parsePITest( TokenStream tokens ) {
+ if (tokens.canConsume("processing-instruction", "(")) {
+ if (tokens.canConsume(")")) return new ProcessingInstructionTest(null);
+ String nameOrStringLiteral = tokens.consume();
+ tokens.consume(")");
+ return new ProcessingInstructionTest(nameOrStringLiteral);
}
+ return null;
+ }
- protected TextTest parseTextTest( TokenStream tokens ) {
- if (tokens.canConsume("text", "(", ")")) {
- return new TextTest();
- }
- return null;
+ protected CommentTest parseCommentTest( TokenStream tokens ) {
+ if (tokens.canConsume("comment", "(", ")")) {
+ return new CommentTest();
}
+ return null;
+ }
- protected DocumentTest parseDocumentTest( TokenStream tokens ) {
- if (tokens.canConsume("document-node", "(")) {
- // Document test ...
- ElementTest elementTest = parseElementTest(tokens);
- DocumentTest result = null;
- if (elementTest != null) {
- result = new DocumentTest(elementTest);
- } else {
- SchemaElementTest schemaTest = parseSchemaElementTest(tokens);
- result = schemaTest != null ? new DocumentTest(schemaTest) : null;
- }
- tokens.consume(")");
- return result;
- }
- return null;
+ protected TextTest parseTextTest( TokenStream tokens ) {
+ if (tokens.canConsume("text", "(", ")")) {
+ return new TextTest();
}
+ return null;
+ }
- protected ElementTest parseElementTest( TokenStream tokens ) {
- if (tokens.canConsume("element", "(")) {
- if (tokens.canConsume(")") || tokens.canConsume("*", ")")) {
- return new ElementTest(new NameTest(null, null), new NameTest(null, null));
- }
- ElementTest result = null;
- NameTest elementName = parseNameTest(tokens);
- if (tokens.canConsume(",")) {
- NameTest typeName = parseNameTest(tokens);
- result = new ElementTest(elementName, typeName);
- } else {
- result = new ElementTest(elementName, new NameTest(null, null));
- }
- tokens.consume(")");
- return result;
+ protected DocumentTest parseDocumentTest( TokenStream tokens ) {
+ if (tokens.canConsume("document-node", "(")) {
+ // Document test ...
+ ElementTest elementTest = parseElementTest(tokens);
+ DocumentTest result = null;
+ if (elementTest != null) {
+ result = new DocumentTest(elementTest);
+ } else {
+ SchemaElementTest schemaTest = parseSchemaElementTest(tokens);
+ result = schemaTest != null ? new DocumentTest(schemaTest) : null;
}
- return null;
+ tokens.consume(")");
+ return result;
}
+ return null;
+ }
- protected SchemaElementTest parseSchemaElementTest( TokenStream tokens ) {
- if (tokens.canConsume("schema-element", "(")) {
- NameTest elementDeclarationName = parseNameTest(tokens);
- SchemaElementTest result = new SchemaElementTest(elementDeclarationName);
- tokens.consume(")");
- return result;
+ protected ElementTest parseElementTest( TokenStream tokens ) {
+ if (tokens.canConsume("element", "(")) {
+ if (tokens.canConsume(")") || tokens.canConsume("*", ")")) {
+ return new ElementTest(new NameTest(null, null), new NameTest(null, null));
}
- return null;
+ ElementTest result = null;
+ NameTest elementName = parseNameTest(tokens);
+ if (tokens.canConsume(",")) {
+ NameTest typeName = parseNameTest(tokens);
+ result = new ElementTest(elementName, typeName);
+ tokens.canConsume('?'); // just eat this
+ } else {
+ result = new ElementTest(elementName, new NameTest(null, null));
+ }
+ tokens.consume(")");
+ return result;
}
+ return null;
+ }
- protected AttributeTest parseAttributeTest( TokenStream tokens ) {
- if (tokens.canConsume("attribute", "(")) {
- if (tokens.canConsume(")") || tokens.canConsume("*", ")")) {
- return new AttributeTest(new NameTest(null, null), new NameTest(null, null));
- }
- AttributeTest result = null;
- NameTest attributeName = parseNameTest(tokens);
- if (tokens.canConsume(",")) {
- NameTest typeName = parseNameTest(tokens);
- result = new AttributeTest(attributeName, typeName);
- } else {
- result = new AttributeTest(attributeName, new NameTest(null, null));
- }
- tokens.consume(")");
- return result;
- }
- return null;
+ protected SchemaElementTest parseSchemaElementTest( TokenStream tokens ) {
+ if (tokens.canConsume("schema-element", "(")) {
+ NameTest elementDeclarationName = parseNameTest(tokens);
+ SchemaElementTest result = new SchemaElementTest(elementDeclarationName);
+ tokens.consume(")");
+ return result;
}
+ return null;
+ }
- protected SchemaAttributeTest parseSchemaAttributeTest( TokenStream tokens ) {
- if (tokens.canConsume("schema-attribute", "(")) {
- NameTest attributeDeclarationName = parseNameTest(tokens);
- SchemaAttributeTest result = new SchemaAttributeTest(attributeDeclarationName);
- tokens.consume(")");
- return result;
+ protected AttributeTest parseAttributeTest( TokenStream tokens ) {
+ if (tokens.canConsume("attribute", "(")) {
+ if (tokens.canConsume(")") || tokens.canConsume("*", ")")) {
+ return new AttributeTest(new NameTest(null, null), new NameTest(null, null));
}
- return null;
+ AttributeTest result = null;
+ NameTest attributeName = parseNameTest(tokens);
+ if (tokens.canConsume(",")) {
+ NameTest typeName = parseNameTest(tokens);
+ result = new AttributeTest(attributeName, typeName);
+ } else {
+ result = new AttributeTest(attributeName, new NameTest(null, null));
+ }
+ tokens.consume(")");
+ return result;
}
+ return null;
+ }
- protected void parseSingleType( TokenStream tokens ) {
+ protected SchemaAttributeTest parseSchemaAttributeTest( TokenStream tokens ) {
+ if (tokens.canConsume("schema-attribute", "(")) {
+ NameTest attributeDeclarationName = parseNameTest(tokens);
+ SchemaAttributeTest result = new SchemaAttributeTest(attributeDeclarationName);
+ tokens.consume(")");
+ return result;
}
+ return null;
+ }
- protected void parseSequenceType( TokenStream tokens ) {
- }
+ protected void parseSingleType( TokenStream tokens ) {
+ }
- /**
- * Remove any leading and trailing single-quotes or double-quotes from the supplied text.
- *
- * @param text the input text; may not be null
- * @return the text without leading and trailing quotes, or <code>text</code> if there were no square brackets or quotes
- */
- protected String removeQuotes( String text ) {
- return text.replaceFirst("^['\"]+", "").replaceAll("['\"]+$", "");
- }
+ protected void parseSequenceType( TokenStream tokens ) {
}
/**
+ * Remove any leading and trailing single-quotes or double-quotes from the supplied text.
+ *
+ * @param text the input text; may not be null
+ * @return the text without leading and trailing quotes, or <code>text</code> if there were no square brackets or quotes
+ */
+ protected String removeQuotes( String text ) {
+ return text.replaceFirst("^['\"]+", "").replaceAll("['\"]+$", "");
+ }
+
+ protected Component collapse( Component component ) {
+ return XPathQueryParser.COLLAPSE_INNER_COMPONENTS ? component.collapse() : component;
+ }
+
+ /**
* A {@link TokenStream.Tokenizer} implementation that parses single- and double-quoted strings, symbols, words consisting of
* {@link TokenStream.CharacterStream#isNextValidXmlNcNameCharacter() NCName}s (as defined by the <a
* href="http://www.w3.org/TR/REC-xml-names/#NT-NCName">Namespaces in XML 1.0</a> specification), XPath comments,and
Added: trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/xpath/XPathQueryParser.java
===================================================================
--- trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/xpath/XPathQueryParser.java (rev 0)
+++ trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/xpath/XPathQueryParser.java 2009-10-03 04:09:29 UTC (rev 1286)
@@ -0,0 +1,65 @@
+/*
+ * JBoss DNA (http://www.jboss.org/dna)
+ * 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.
+ * See the AUTHORS.txt file in the distribution for a full listing of
+ * individual contributors.
+ *
+ * JBoss DNA is free software. Unless otherwise indicated, all code in JBoss DNA
+ * is licensed to you 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.
+ *
+ * JBoss DNA 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 software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.dna.jcr.xpath;
+
+import org.jboss.dna.common.text.ParsingException;
+import org.jboss.dna.graph.ExecutionContext;
+import org.jboss.dna.graph.query.model.QueryCommand;
+import org.jboss.dna.graph.query.parse.InvalidQueryException;
+import org.jboss.dna.graph.query.parse.QueryParser;
+import org.jboss.dna.jcr.xpath.XPath.Component;
+
+/**
+ * A {@link QueryParser} implementation that accepts XPath expressions and converts them to a {@link QueryCommand DNA Abstract
+ * Query Model} representation.
+ */
+public class XPathQueryParser implements QueryParser {
+
+ static final boolean COLLAPSE_INNER_COMPONENTS = true;
+ private static final String LANGUAGE = "XPath";
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.jboss.dna.graph.query.parse.QueryParser#getLanguage()
+ */
+ public String getLanguage() {
+ return LANGUAGE;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.jboss.dna.graph.query.parse.QueryParser#parseQuery(java.lang.String, org.jboss.dna.graph.ExecutionContext)
+ */
+ public QueryCommand parseQuery( String query,
+ ExecutionContext context ) throws InvalidQueryException, ParsingException {
+ Component xpath = new XPathParser(context).parseXPath(query);
+ System.out.println(query);
+ System.out.println(" --> " + xpath);
+ // Convert the result into a QueryCommand ...
+ QueryCommand command = new XPathToQueryTranslator(context, query).createQuery(xpath);
+ return command;
+ }
+}
Property changes on: trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/xpath/XPathQueryParser.java
___________________________________________________________________
Name: svn:keywords
+ Id Revision
Name: svn:eol-style
+ LF
Added: trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/xpath/XPathToQueryTranslator.java
===================================================================
--- trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/xpath/XPathToQueryTranslator.java (rev 0)
+++ trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/xpath/XPathToQueryTranslator.java 2009-10-03 04:09:29 UTC (rev 1286)
@@ -0,0 +1,807 @@
+/*
+ * JBoss DNA (http://www.jboss.org/dna)
+ * 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.
+ * See the AUTHORS.txt file in the distribution for a full listing of
+ * individual contributors.
+ *
+ * JBoss DNA is free software. Unless otherwise indicated, all code in JBoss DNA
+ * is licensed to you 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.
+ *
+ * JBoss DNA 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 software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.dna.jcr.xpath;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import org.jboss.dna.graph.ExecutionContext;
+import org.jboss.dna.graph.property.PropertyType;
+import org.jboss.dna.graph.query.QueryBuilder;
+import org.jboss.dna.graph.query.QueryBuilder.ConstraintBuilder;
+import org.jboss.dna.graph.query.model.Operator;
+import org.jboss.dna.graph.query.model.QueryCommand;
+import org.jboss.dna.graph.query.parse.InvalidQueryException;
+import org.jboss.dna.jcr.xpath.XPath.And;
+import org.jboss.dna.jcr.xpath.XPath.AttributeNameTest;
+import org.jboss.dna.jcr.xpath.XPath.AxisStep;
+import org.jboss.dna.jcr.xpath.XPath.BinaryComponent;
+import org.jboss.dna.jcr.xpath.XPath.Comparison;
+import org.jboss.dna.jcr.xpath.XPath.Component;
+import org.jboss.dna.jcr.xpath.XPath.ContextItem;
+import org.jboss.dna.jcr.xpath.XPath.DescendantOrSelf;
+import org.jboss.dna.jcr.xpath.XPath.ElementTest;
+import org.jboss.dna.jcr.xpath.XPath.Except;
+import org.jboss.dna.jcr.xpath.XPath.FilterStep;
+import org.jboss.dna.jcr.xpath.XPath.FunctionCall;
+import org.jboss.dna.jcr.xpath.XPath.Intersect;
+import org.jboss.dna.jcr.xpath.XPath.Literal;
+import org.jboss.dna.jcr.xpath.XPath.NameTest;
+import org.jboss.dna.jcr.xpath.XPath.NodeTest;
+import org.jboss.dna.jcr.xpath.XPath.Or;
+import org.jboss.dna.jcr.xpath.XPath.ParenthesizedExpression;
+import org.jboss.dna.jcr.xpath.XPath.PathExpression;
+import org.jboss.dna.jcr.xpath.XPath.StepExpression;
+import org.jboss.dna.jcr.xpath.XPath.Union;
+
+/**
+ * A component that translates an {@link XPath} abstract syntax model representation into a {@link QueryCommand DNA abstract query
+ * model}.
+ */
+public class XPathToQueryTranslator {
+
+ protected static final Map<NameTest, PropertyType> CAST_FUNCTION_NAME_TO_TYPE;
+
+ static {
+ Map<NameTest, PropertyType> map = new HashMap<NameTest, PropertyType>();
+ map.put(new NameTest("fn", "string"), PropertyType.STRING);
+ map.put(new NameTest("xs", "string"), PropertyType.STRING);
+ map.put(new NameTest("xs", "base64Binary"), PropertyType.BINARY);
+ map.put(new NameTest("xs", "double"), PropertyType.DOUBLE);
+ map.put(new NameTest("xs", "long"), PropertyType.LONG);
+ map.put(new NameTest("xs", "boolean"), PropertyType.BOOLEAN);
+ map.put(new NameTest("xs", "dateTime"), PropertyType.DATE);
+ map.put(new NameTest("xs", "string"), PropertyType.PATH);
+ map.put(new NameTest("xs", "string"), PropertyType.NAME);
+ map.put(new NameTest("xs", "IDREF"), PropertyType.REFERENCE);
+ CAST_FUNCTION_NAME_TO_TYPE = Collections.unmodifiableMap(map);
+ }
+
+ private final String query;
+ private final ExecutionContext context;
+ private final QueryBuilder builder;
+ private final Set<String> aliases = new HashSet<String>();
+
+ public XPathToQueryTranslator( ExecutionContext context,
+ String query ) {
+ this.query = query;
+ this.context = context;
+ this.builder = new QueryBuilder(this.context);
+ }
+
+ public QueryCommand createQuery( Component xpath ) {
+ if (xpath instanceof BinaryComponent) {
+ BinaryComponent binary = (BinaryComponent)xpath;
+ if (binary instanceof Union) {
+ createQuery(binary.getLeft());
+ builder.union();
+ createQuery(binary.getRight());
+ return builder.query();
+ } else if (binary instanceof Intersect) {
+ createQuery(binary.getLeft());
+ builder.intersect();
+ createQuery(binary.getRight());
+ return builder.query();
+ } else if (binary instanceof Except) {
+ createQuery(binary.getLeft());
+ builder.except();
+ createQuery(binary.getRight());
+ return builder.query();
+ }
+ } else if (xpath instanceof PathExpression) {
+ translate((PathExpression)xpath);
+ return builder.query();
+ }
+ // unexpected component ...
+ throw new InvalidQueryException(query,
+ "Acceptable XPath queries must lead with a path expression or must be a union, intersect or except");
+ }
+
+ protected void translate( PathExpression pathExpression ) {
+ List<StepExpression> steps = pathExpression.getSteps();
+ assert !steps.isEmpty();
+ if (!pathExpression.isRelative()) {
+ // Absolute path must start with "/jcr:root/" or "//" ...
+ Component first = steps.get(0).collapse();
+ // Result will be NameTest("jcr","root") or DescendantOrSelf ...
+ if (first instanceof DescendantOrSelf) {
+ // do nothing ...
+ } else if (first instanceof NameTest && steps.size() > 1 && ((NameTest)first).matches("jcr", "root")) {
+ // We can actually remove this first step, since relative paths are relative to the root ...
+ steps = steps.subList(1, steps.size());
+ } else {
+ throw new InvalidQueryException(query, "An absolute path expression must start with '//' or '/jcr:root/...'");
+ }
+ }
+
+ // Walk the steps along the path expression ...
+ ConstraintBuilder where = builder.where();
+ List<StepExpression> path = new ArrayList<StepExpression>();
+ String tableName = null;
+ for (StepExpression step : steps) {
+ if (step instanceof AxisStep) {
+ AxisStep axis = (AxisStep)step;
+ NodeTest nodeTest = axis.getNodeTest();
+ if (nodeTest instanceof NameTest) {
+ if (appliesToPathConstraint(axis.getPredicates())) {
+ // Can go into the path constraint ...
+ path.add(step);
+ } else {
+ // The constraints are more complicated, so we need to define a new source/table ...
+ // path.add(step);
+ tableName = translateSource(tableName, path, where);
+ translatePredicates(axis.getPredicates(), tableName, where);
+ path.clear();
+ }
+ } else if (nodeTest instanceof ElementTest) {
+ // We need to build a new source with the partial path we have so far ...
+ tableName = translateElementTest((ElementTest)nodeTest, path, where);
+ translatePredicates(axis.getPredicates(), tableName, where);
+ path.clear();
+ } else if (nodeTest instanceof AttributeNameTest) {
+ AttributeNameTest attributeName = (AttributeNameTest)nodeTest;
+ builder.select(nameFrom(attributeName.getNameTest()));
+ } else {
+ throw new InvalidQueryException(query, "The '" + step + "' step is not supported");
+ }
+ } else if (step instanceof FilterStep) {
+ FilterStep filter = (FilterStep)step;
+ Component primary = filter.getPrimaryExpression();
+ List<Component> predicates = filter.getPredicates();
+ if (primary instanceof ContextItem) {
+ if (appliesToPathConstraint(predicates)) {
+ // Can ignore the '.' ...
+ } else {
+ // The constraints are more complicated, so we need to define a new source/table ...
+ path.add(step);
+ tableName = translateSource(tableName, path, where);
+ translatePredicates(predicates, tableName, where);
+ path.clear();
+ }
+ } else if (primary instanceof Literal) {
+ throw new InvalidQueryException(query,
+ "A literal is not supported in the primary path expression; therefore '"
+ + primary + "' is not valid");
+ } else if (primary instanceof FunctionCall) {
+ throw new InvalidQueryException(query,
+ "A function call is not supported in the primary path expression; therefore '"
+ + primary + "' is not valid");
+ } else if (primary instanceof ParenthesizedExpression) {
+ // This can be used to define an OR-ed set of expressions defining select columns ...
+ ParenthesizedExpression paren = (ParenthesizedExpression)primary;
+ Component wrapped = paren.getWrapped().collapse();
+ if (wrapped instanceof AttributeNameTest) {
+ AttributeNameTest attributeName = (AttributeNameTest)wrapped;
+ builder.select(nameFrom(attributeName.getNameTest()));
+ } else if (wrapped instanceof BinaryComponent) {
+ for (AttributeNameTest attributeName : extractAttributeNames((BinaryComponent)wrapped)) {
+ builder.select(nameFrom(attributeName.getNameTest()));
+ }
+ path.add(filter); // in case any element names are there
+ } else {
+ throw new InvalidQueryException(query,
+ "A parenthesized expression of this type is not supported in the primary path expression; therefore '"
+ + primary + "' is not valid");
+ }
+ }
+
+ } else {
+ path.add(step);
+ }
+ }
+ if (!path.isEmpty()) {
+ translateSource(tableName, path, where);
+ }
+ where.end();
+ }
+
+ /**
+ * Find any {@link AttributeNameTest attribute names} that have been unioned together (with '|'). Any other combination of
+ * objects results in an error.
+ *
+ * @param binary the binary component
+ * @return the list of attribute names, if that's all that's in the supplied component; may be empty
+ */
+ protected List<AttributeNameTest> extractAttributeNames( BinaryComponent binary ) {
+ List<AttributeNameTest> results = new ArrayList<AttributeNameTest>();
+ boolean failed = false;
+ if (binary instanceof Union) {
+ for (int i = 0; i != 2; ++i) {
+ Component comp = i == 0 ? binary.getLeft() : binary.getRight();
+ comp = comp.collapse();
+ if (comp instanceof Union) {
+ results.addAll(extractAttributeNames((BinaryComponent)comp));
+ } else if (comp instanceof AttributeNameTest) {
+ results.add((AttributeNameTest)comp);
+ } else if (comp instanceof NameTest) {
+ // Element names, which are fine but we'll ignore
+ } else {
+ failed = true;
+ break;
+ }
+ }
+ } else {
+ failed = true;
+ }
+ if (failed) {
+ throw new InvalidQueryException(query,
+ "A parenthesized expression in a path step may only contain ORed and ANDed attribute names or element names; therefore '"
+ + binary + "' is not valid");
+ }
+ return results;
+ }
+
+ /**
+ * Find any {@link NameTest element names} that have been unioned together (with '|'). Any other combination of objects
+ * results in an error.
+ *
+ * @param binary the binary component
+ * @return the list of attribute names, if that's all that's in the supplied component; may be empty
+ */
+ protected List<NameTest> extractElementNames( BinaryComponent binary ) {
+ List<NameTest> results = new ArrayList<NameTest>();
+ boolean failed = false;
+ if (binary instanceof Union) {
+ for (int i = 0; i != 2; ++i) {
+ Component comp = i == 0 ? binary.getLeft() : binary.getRight();
+ comp = comp.collapse();
+ if (comp instanceof Union) {
+ results.addAll(extractElementNames((BinaryComponent)comp));
+ } else if (comp instanceof AttributeNameTest) {
+ // ignore these ...
+ } else if (comp instanceof NameTest) {
+ results.add((NameTest)comp);
+ } else {
+ failed = true;
+ break;
+ }
+ }
+ } else {
+ failed = true;
+ }
+ if (failed) {
+ throw new InvalidQueryException(query,
+ "A parenthesized expression in a path step may only contain ORed element names; therefore '"
+ + binary + "' is not valid");
+ }
+ return results;
+ }
+
+ protected String translateSource( String tableName,
+ List<StepExpression> path,
+ ConstraintBuilder where ) {
+ String alias = newAlias();
+ if (tableName != null) {
+ // This is after some element(...) steps, so we need to join ...
+ builder.joinAllNodesAs(alias);
+ } else {
+ // This is the only part of the query ...
+ builder.fromAllNodesAs(alias);
+ }
+ tableName = alias;
+ if (path.size() == 1 && path.get(0).collapse() instanceof NameTest) {
+ // Node immediately below root ...
+ NameTest nodeName = (NameTest)path.get(0).collapse();
+ where.nodeName(alias).isEqualTo(nameFrom(nodeName)).and().depth(alias).isEqualTo(1);
+ } else if (path.size() == 2 && path.get(0) instanceof DescendantOrSelf && path.get(1).collapse() instanceof NameTest) {
+ // Node anywhere ...
+ NameTest nodeName = (NameTest)path.get(1).collapse();
+ if (!nodeName.isWildcard()) {
+ where.nodeName(alias).isEqualTo(nameFrom(nodeName));
+ }
+ } else {
+ // Must be just a bunch of descendant-or-self, axis and filter steps ...
+ translatePathExpressionConstraint(new PathExpression(true, path), where, alias);
+ }
+ return tableName;
+ }
+
+ protected String translateElementTest( ElementTest elementTest,
+ List<StepExpression> pathConstraint,
+ ConstraintBuilder where ) {
+ String tableName = null;
+ NameTest typeName = elementTest.getTypeName();
+ if (typeName.isWildcard()) {
+ tableName = newAlias();
+ builder.fromAllNodesAs(tableName);
+ } else {
+ if (typeName.getLocalTest() == null) {
+ throw new InvalidQueryException(
+ query,
+ "The '"
+ + elementTest
+ + "' clause uses a partial wildcard in the type name, but only a wildcard on the whole name is supported");
+ }
+ tableName = nameFrom(typeName);
+ builder.from(tableName);
+ }
+ if (elementTest.getElementName() != null) {
+ NameTest nodeName = elementTest.getElementName();
+ if (!nodeName.isWildcard()) {
+ where.nodeName(tableName).isEqualTo(nameFrom(nodeName));
+ }
+ }
+ if (pathConstraint.isEmpty()) {
+ where.depth(tableName).isEqualTo(1);
+ }
+ return tableName;
+ }
+
+ protected void translatePredicates( List<Component> predicates,
+ String tableName,
+ ConstraintBuilder where ) {
+ assert tableName != null;
+ for (Component predicate : predicates) {
+ translatePredicate(predicate, tableName, where);
+ }
+ }
+
+ protected String translatePredicate( Component predicate,
+ String tableName,
+ ConstraintBuilder where ) {
+ predicate = predicate.collapse();
+ assert tableName != null;
+ if (predicate instanceof ParenthesizedExpression) {
+ ParenthesizedExpression paren = (ParenthesizedExpression)predicate;
+ where = where.openParen();
+ translatePredicate(paren.getWrapped(), tableName, where);
+ where.closeParen();
+ } else if (predicate instanceof And) {
+ And and = (And)predicate;
+ where = where.openParen();
+ translatePredicate(and.getLeft(), tableName, where);
+ where.and();
+ translatePredicate(and.getRight(), tableName, where);
+ where.closeParen();
+ } else if (predicate instanceof Or) {
+ Or or = (Or)predicate;
+ where = where.openParen();
+ translatePredicate(or.getLeft(), tableName, where);
+ where.or();
+ translatePredicate(or.getRight(), tableName, where);
+ where.closeParen();
+ } else if (predicate instanceof Union) {
+ Union union = (Union)predicate;
+ where = where.openParen();
+ translatePredicate(union.getLeft(), tableName, where);
+ where.or();
+ translatePredicate(union.getRight(), tableName, where);
+ where.closeParen();
+ } else if (predicate instanceof Literal) {
+ Literal literal = (Literal)predicate;
+ if (literal.isInteger()) return tableName; // do nothing, since this is a path constraint and is handled elsewhere
+ } else if (predicate instanceof AttributeNameTest) {
+ // This adds the criteria that the attribute exists, and adds it to the select ...
+ AttributeNameTest attribute = (AttributeNameTest)predicate;
+ String propertyName = nameFrom(attribute.getNameTest());
+ where.hasProperty(tableName, propertyName);
+ } else if (predicate instanceof NameTest) {
+ // This adds the criteria that the child node exists ...
+ NameTest childName = (NameTest)predicate;
+ String alias = newAlias();
+ builder.joinAllNodesAs(alias).onChildNode(tableName, alias);
+ if (!childName.isWildcard()) where.nodeName(alias).isEqualTo(nameFrom(childName));
+ tableName = alias;
+ } else if (predicate instanceof Comparison) {
+ Comparison comparison = (Comparison)predicate;
+ Component left = comparison.getLeft();
+ Component right = comparison.getRight();
+ Operator operator = comparison.getOperator();
+ if (left instanceof Literal) {
+ Component temp = left;
+ left = right;
+ right = temp;
+ operator = operator.getReverse();
+ }
+ if (left instanceof AttributeNameTest) {
+ AttributeNameTest attribute = (AttributeNameTest)left;
+ String propertyName = nameFrom(attribute.getNameTest());
+ if (right instanceof Literal) {
+ String value = ((Literal)right).getValue();
+ where.propertyValue(tableName, propertyName).is(operator, value);
+ } else if (right instanceof FunctionCall) {
+ FunctionCall call = (FunctionCall)right;
+ NameTest functionName = call.getName();
+ List<Component> parameters = call.getParameters();
+ // Is this a cast ...
+ PropertyType castType = CAST_FUNCTION_NAME_TO_TYPE.get(functionName);
+ if (castType != null) {
+ if (parameters.size() == 1 && parameters.get(0).collapse() instanceof Literal) {
+ // The first parameter can be the type name (or table name) ...
+ Literal value = (Literal)parameters.get(0).collapse();
+ where.propertyValue(tableName, propertyName).is(operator).cast(value.getValue()).as(castType);
+ } else {
+ throw new InvalidQueryException(query, "A cast function requires one literal parameter; therefore '"
+ + comparison + "' is not valid");
+ }
+ } else {
+ throw new InvalidQueryException(query,
+ "Only the 'jcr:score' function is allowed in a comparison predicate; therefore '"
+ + comparison + "' is not valid");
+ }
+ }
+ } else if (left instanceof FunctionCall && right instanceof Literal) {
+ FunctionCall call = (FunctionCall)left;
+ NameTest functionName = call.getName();
+ List<Component> parameters = call.getParameters();
+ String value = ((Literal)right).getValue();
+ if (functionName.matches("jcr", "score")) {
+ String scoreTableName = tableName;
+ if (parameters.isEmpty()) {
+ scoreTableName = tableName;
+ } else if (parameters.size() == 1 && parameters.get(0) instanceof NameTest) {
+ // The first parameter can be the type name (or table name) ...
+ NameTest name = (NameTest)parameters.get(0);
+ if (!name.isWildcard()) scoreTableName = nameFrom(name);
+ } else {
+ throw new InvalidQueryException(query,
+ "The 'jcr:score' function may have no parameters or the type name as the only parameter.");
+
+ }
+ where.fullTextSearchScore(scoreTableName).is(operator, value);
+ } else {
+ throw new InvalidQueryException(query,
+ "Only the 'jcr:score' function is allowed in a comparison predicate; therefore '"
+ + comparison + "' is not valid");
+ }
+ }
+ } else if (predicate instanceof FunctionCall) {
+ FunctionCall call = (FunctionCall)predicate;
+ NameTest functionName = call.getName();
+ List<Component> parameters = call.getParameters();
+ Component param1 = parameters.size() > 0 ? parameters.get(0) : null;
+ Component param2 = parameters.size() > 1 ? parameters.get(1) : null;
+ if (functionName.matches(null, "not")) {
+ if (parameters.size() != 1) {
+ throw new InvalidQueryException(query, "The 'not' function requires one parameter; therefore '" + predicate
+ + "' is not valid");
+ }
+ where = where.not().openParen();
+ translatePredicate(param1, tableName, where);
+ where.closeParen();
+ } else if (functionName.matches("jcr", "like")) {
+ if (parameters.size() != 2) {
+ throw new InvalidQueryException(query, "The 'jcr:like' function requires two parameters; therefore '"
+ + predicate + "' is not valid");
+ }
+ if (!(param1 instanceof AttributeNameTest)) {
+ throw new InvalidQueryException(query,
+ "The first parameter of 'jcr:like' must be an property reference with the '@' symbol; therefore '"
+ + predicate + "' is not valid");
+ }
+ if (!(param2 instanceof Literal)) {
+ throw new InvalidQueryException(query, "The second parameter of 'jcr:like' must be a literal; therefore '"
+ + predicate + "' is not valid");
+ }
+ NameTest attributeName = ((AttributeNameTest)param1).getNameTest();
+ String value = ((Literal)param2).getValue();
+ where.propertyValue(tableName, nameFrom(attributeName)).isLike(value);
+ } else if (functionName.matches("jcr", "contains")) {
+ if (parameters.size() != 2) {
+ throw new InvalidQueryException(query, "The 'jcr:contains' function requires two parameters; therefore '"
+ + predicate + "' is not valid");
+ }
+ if (!(param2 instanceof Literal)) {
+ throw new InvalidQueryException(query,
+ "The second parameter of 'jcr:contains' must be a literal; therefore '"
+ + predicate + "' is not valid");
+ }
+ String value = ((Literal)param2).getValue();
+ if (param1 instanceof ContextItem) {
+ // refers to the current node (or table) ...
+ where.search(tableName, value);
+ } else if (param1 instanceof AttributeNameTest) {
+ // refers to an attribute on the current node (or table) ...
+ NameTest attributeName = ((AttributeNameTest)param1).getNameTest();
+ where.search(tableName, nameFrom(attributeName), value);
+ } else if (param1 instanceof NameTest) {
+ // refers to child node, so we need to add a join ...
+ String alias = newAlias();
+ builder.joinAllNodesAs(alias).onChildNode(tableName, alias);
+ // Now add the criteria ...
+ where.search(alias, value);
+ tableName = alias;
+ } else if (param1 instanceof PathExpression) {
+ // refers to a descendant node ...
+ PathExpression pathExpr = (PathExpression)param1;
+ if (pathExpr.getLastStep().collapse() instanceof AttributeNameTest) {
+ AttributeNameTest attributeName = (AttributeNameTest)pathExpr.getLastStep().collapse();
+ pathExpr = pathExpr.withoutLast();
+ String searchTable = translatePredicate(pathExpr, tableName, where);
+ if (attributeName.getNameTest().isWildcard()) {
+ where.search(searchTable, value);
+ } else {
+ where.search(searchTable, nameFrom(attributeName.getNameTest()), value);
+ }
+ } else {
+ String searchTable = translatePredicate(param1, tableName, where);
+ where.search(searchTable, value);
+ }
+ } else {
+ throw new InvalidQueryException(query,
+ "The first parameter of 'jcr:contains' must be a relative path (e.g., '.', an attribute name, a child name, etc.); therefore '"
+ + predicate + "' is not valid");
+ }
+ } else if (functionName.matches("jcr", "deref")) {
+ throw new InvalidQueryException(query,
+ "The 'jcr:deref' function is not required by JCR and is not currently supported; therefore '"
+ + predicate + "' is not valid");
+ } else {
+ throw new InvalidQueryException(query,
+ "Only the 'jcr:like' and 'jcr:contains' functions are allowed in a predicate; therefore '"
+ + predicate + "' is not valid");
+ }
+ } else if (predicate instanceof PathExpression) {
+ // Requires that the descendant node with the relative path does exist ...
+ PathExpression pathExpr = (PathExpression)predicate;
+ List<StepExpression> steps = pathExpr.getSteps();
+ assert steps.size() > 1; // 1 or 0 would have been collapsed ...
+ Component firstStep = steps.get(0).collapse();
+ if (firstStep instanceof ContextItem) {
+ // Remove the context and retry ...
+ return translatePredicate(new PathExpression(true, steps.subList(1, steps.size())), tableName, where);
+ }
+ if (firstStep instanceof NameTest) {
+ // Special case where this is similar to '[a/@id]'
+ NameTest childName = (NameTest)firstStep;
+ String alias = newAlias();
+ builder.joinAllNodesAs(alias).onChildNode(tableName, alias);
+ if (!childName.isWildcard()) {
+ where.nodeName(alias).isEqualTo(nameFrom(childName));
+ }
+ return translatePredicate(new PathExpression(true, steps.subList(1, steps.size())), alias, where);
+ }
+ if (firstStep instanceof DescendantOrSelf) {
+ // Special case where this is similar to '[a/@id]'
+ String alias = newAlias();
+ builder.joinAllNodesAs(alias).onDescendant(tableName, alias);
+ return translatePredicate(new PathExpression(true, steps.subList(1, steps.size())), alias, where);
+ }
+ // Add the join ...
+ String alias = newAlias();
+ builder.joinAllNodesAs(alias).onDescendant(tableName, alias);
+ // Now add the criteria ...
+ translatePathExpressionConstraint(pathExpr, where, alias);
+ } else {
+ throw new InvalidQueryException(query, "Unsupported criteria '" + predicate + "'");
+ }
+ return tableName;
+ }
+
+ /**
+ * Determine if the predicates contain any expressions that cannot be put into a LIKE constraint on the path.
+ *
+ * @param predicates the predicates
+ * @return true if the supplied predicates can be handled entirely in the LIKE constraint on the path, or false if they have
+ * to be handled as other criteria
+ */
+ protected boolean appliesToPathConstraint( List<Component> predicates ) {
+ if (predicates.isEmpty()) return true;
+ if (predicates.size() > 1) return false;
+ assert predicates.size() == 1;
+ Component predicate = predicates.get(0);
+ if (predicate instanceof Literal && ((Literal)predicate).isInteger()) return true;
+ if (predicate instanceof NameTest && ((NameTest)predicate).isWildcard()) return true;
+ return false;
+ }
+
+ protected boolean translatePathExpressionConstraint( PathExpression pathExrp,
+ ConstraintBuilder where,
+ String tableName ) {
+ String[] paths = relativePathLikeExpressions(pathExrp);
+ if (paths == null || paths.length == 0) return false;
+ where = where.openParen();
+ boolean first = true;
+ int number = 0;
+ for (String path : paths) {
+ if (path == null || path.length() == 0 || path.equals("%/")) continue;
+ if (first) first = false;
+ else where.or();
+ if (path.indexOf('%') != -1) {
+ where.path(tableName).isLike(path);
+ } else {
+ where.path(tableName).isEqualTo(path);
+ }
+ ++number;
+ }
+ if (number > 0) where.closeParen();
+ return true;
+ }
+
+ protected String[] relativePathLikeExpressions( PathExpression pathExpression ) {
+ List<StepExpression> steps = pathExpression.getSteps();
+ if (steps.isEmpty()) return new String[] {};
+ if (steps.size() == 1 && steps.get(0) instanceof DescendantOrSelf) return new String[] {};
+ PathLikeBuilder builder = new SinglePathLikeBuilder();
+ for (StepExpression step : steps) {
+ if (step instanceof DescendantOrSelf) {
+ if (builder.isEmpty()) {
+ builder.append("%/");
+ } else {
+ builder = new DualPathLikeBuilder(builder.clone(), builder.append("/%"));
+ }
+ } else if (step instanceof AxisStep) {
+ AxisStep axis = (AxisStep)step;
+ NodeTest nodeTest = axis.getNodeTest();
+ assert !(nodeTest instanceof ElementTest);
+ if (nodeTest instanceof NameTest) {
+ NameTest nameTest = (NameTest)nodeTest;
+ builder.append('/');
+ if (nameTest.getPrefixTest() != null) {
+ builder.append(nameTest.getPrefixTest()).append(':');
+ }
+ if (nameTest.getLocalTest() != null) {
+ builder.append(nameTest.getLocalTest());
+ } else {
+ builder.append('%');
+ }
+ List<Component> predicates = axis.getPredicates();
+ if (!predicates.isEmpty()) {
+ assert predicates.size() == 1;
+ Component predicate = predicates.get(0);
+ if (predicate instanceof Literal && ((Literal)predicate).isInteger()) {
+ builder.append('[').append(((Literal)predicate).getValue()).append(']');
+ }
+ }
+ }
+ } else if (step instanceof FilterStep) {
+ FilterStep filter = (FilterStep)step;
+ Component primary = filter.getPrimaryExpression();
+ if (primary instanceof ContextItem) {
+ continue; // ignore this '.'
+ } else if (primary instanceof ParenthesizedExpression) {
+ ParenthesizedExpression paren = (ParenthesizedExpression)primary;
+ Component wrapped = paren.getWrapped().collapse();
+ if (wrapped instanceof AttributeNameTest) {
+ // ignore this; handled earlier ...
+ } else if (wrapped instanceof BinaryComponent) {
+ List<NameTest> names = extractElementNames((BinaryComponent)wrapped);
+ if (names.size() >= 1) {
+ PathLikeBuilder orig = builder.clone();
+ builder.append('/').append(nameFrom(names.get(0)));
+ if (names.size() > 1) {
+ for (NameTest name : names.subList(1, names.size())) {
+ builder = new DualPathLikeBuilder(orig.clone().append('/').append(nameFrom(name)), builder);
+ }
+ }
+ }
+ } else {
+ throw new InvalidQueryException(query,
+ "A parenthesized expression of this type is not supported in the primary path expression; therefore '"
+ + primary + "' is not valid");
+ }
+ }
+ }
+ }
+ return builder.getPaths();
+ }
+
+ protected static interface PathLikeBuilder {
+ PathLikeBuilder append( String string );
+
+ PathLikeBuilder append( char c );
+
+ boolean isEmpty();
+
+ PathLikeBuilder clone();
+
+ String[] getPaths();
+ }
+
+ protected static class SinglePathLikeBuilder implements PathLikeBuilder {
+ private final StringBuilder builder = new StringBuilder();
+
+ public SinglePathLikeBuilder append( String string ) {
+ builder.append(string);
+ return this;
+ }
+
+ public SinglePathLikeBuilder append( char c ) {
+ builder.append(c);
+ return this;
+ }
+
+ public boolean isEmpty() {
+ return builder.length() == 0;
+ }
+
+ @Override
+ public SinglePathLikeBuilder clone() {
+ return new SinglePathLikeBuilder().append(builder.toString());
+ }
+
+ @Override
+ public String toString() {
+ return builder.toString();
+ }
+
+ public String[] getPaths() {
+ return isEmpty() ? new String[] {} : new String[] {builder.toString()};
+ }
+ }
+
+ protected static class DualPathLikeBuilder implements PathLikeBuilder {
+ private final PathLikeBuilder builder1;
+ private final PathLikeBuilder builder2;
+
+ protected DualPathLikeBuilder( PathLikeBuilder builder1,
+ PathLikeBuilder builder2 ) {
+ this.builder1 = builder1;
+ this.builder2 = builder2;
+ }
+
+ public DualPathLikeBuilder append( String string ) {
+ builder1.append(string);
+ builder2.append(string);
+ return this;
+ }
+
+ public DualPathLikeBuilder append( char c ) {
+ builder1.append(c);
+ builder2.append(c);
+ return this;
+ }
+
+ public boolean isEmpty() {
+ return false;
+ }
+
+ @Override
+ public DualPathLikeBuilder clone() {
+ return new DualPathLikeBuilder(builder1.clone(), builder2.clone());
+ }
+
+ public String[] getPaths() {
+ String[] paths1 = builder1.getPaths();
+ String[] paths2 = builder2.getPaths();
+ String[] result = new String[paths1.length + paths2.length];
+ System.arraycopy(paths1, 0, result, 0, paths1.length);
+ System.arraycopy(paths2, 0, result, paths1.length, paths2.length);
+ return result;
+ }
+ }
+
+ protected String nameFrom( NameTest name ) {
+ String prefix = name.getPrefixTest();
+ String local = name.getLocalTest();
+ assert local != null;
+ return (prefix != null ? prefix + ":" : "") + local;
+ }
+
+ protected String newAlias() {
+ String root = "nodeSet";
+ int num = 1;
+ String alias = root + num;
+ while (aliases.contains(alias)) {
+ num += 1;
+ alias = root + num;
+ }
+ aliases.add(alias);
+ return alias;
+ }
+}
Property changes on: trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/xpath/XPathToQueryTranslator.java
___________________________________________________________________
Name: svn:keywords
+ Id Revision
Name: svn:eol-style
+ LF
Modified: trunk/dna-jcr/src/test/java/org/jboss/dna/jcr/xpath/XPathParserTest.java
===================================================================
--- trunk/dna-jcr/src/test/java/org/jboss/dna/jcr/xpath/XPathParserTest.java 2009-10-03 04:07:41 UTC (rev 1285)
+++ trunk/dna-jcr/src/test/java/org/jboss/dna/jcr/xpath/XPathParserTest.java 2009-10-03 04:09:29 UTC (rev 1286)
@@ -36,11 +36,13 @@
import org.jboss.dna.common.text.TokenStream.Tokenizer;
import org.jboss.dna.graph.ExecutionContext;
import org.jboss.dna.graph.query.model.Operator;
+import org.jboss.dna.jcr.xpath.XPath.And;
import org.jboss.dna.jcr.xpath.XPath.AnyKindTest;
import org.jboss.dna.jcr.xpath.XPath.AttributeNameTest;
import org.jboss.dna.jcr.xpath.XPath.AttributeTest;
import org.jboss.dna.jcr.xpath.XPath.AxisStep;
import org.jboss.dna.jcr.xpath.XPath.CommentTest;
+import org.jboss.dna.jcr.xpath.XPath.Comparison;
import org.jboss.dna.jcr.xpath.XPath.Component;
import org.jboss.dna.jcr.xpath.XPath.ContextItem;
import org.jboss.dna.jcr.xpath.XPath.DescendantOrSelf;
@@ -51,15 +53,16 @@
import org.jboss.dna.jcr.xpath.XPath.Literal;
import org.jboss.dna.jcr.xpath.XPath.NameTest;
import org.jboss.dna.jcr.xpath.XPath.NodeTest;
+import org.jboss.dna.jcr.xpath.XPath.Or;
import org.jboss.dna.jcr.xpath.XPath.ParenthesizedExpression;
import org.jboss.dna.jcr.xpath.XPath.PathExpression;
import org.jboss.dna.jcr.xpath.XPath.SchemaAttributeTest;
import org.jboss.dna.jcr.xpath.XPath.SchemaElementTest;
import org.jboss.dna.jcr.xpath.XPath.StepExpression;
import org.jboss.dna.jcr.xpath.XPath.TextTest;
-import org.jboss.dna.jcr.xpath.XPathParser.XPathTokenizer;
import org.junit.After;
import org.junit.Before;
+import org.junit.Ignore;
import org.junit.Test;
/**
@@ -68,12 +71,12 @@
public class XPathParserTest {
private ExecutionContext context;
- private XPathParser.Parser parser;
+ private XPathParser parser;
@Before
public void beforeEach() {
context = new ExecutionContext();
- parser = new XPathParser.Parser(context);
+ parser = new XPathParser(context);
}
@After
@@ -85,19 +88,59 @@
public void shouldParseXPathExpressions() {
assertParsable("/jcr:root/a/b/c");
assertParsable("/jcr:root/a/b/c[*]");
- assertParsable("/jcr:root/some[1]/element(nodes, my:type)[1]");
+ assertParsable("/jcr:root/some[1]/element(nodes, my:type)[2]");
assertParsable("//element(*,my:type)");
assertParsable("//element(*,my:type)[@jcr:title='something' and @globalProperty='something else']");
assertParsable("//element(*,my:type)[@jcr:title | @globalProperty]");
+ assertParsable("//element(*,my:type)/(@jcr:title | @globalProperty)");
assertParsable("//element(*, my:type) order by @my:title");
assertParsable("//element(*, my:type) [jcr:contains(., 'jcr')] order by jcr:score() descending");
assertParsable("//element(*, employee)[@secretary and @assistant]");
+ assertParsable("//element(*, employee)[@secretary or @assistant]");
}
@Test
+ public void shouldParseXPathExpressions2() {
+ assertParsable("/jcr:root/a/b/c", pathExpr(axisStep(nameTest("jcr", "root")),
+ axisStep(nameTest("a")),
+ axisStep(nameTest("b")),
+ axisStep(nameTest("c"))));
+ assertParsable("/jcr:root/a/b/c[*]", pathExpr(axisStep(nameTest("jcr", "root")),
+ axisStep(nameTest("a")),
+ axisStep(nameTest("b")),
+ axisStep(nameTest("c"), wildcard())));
+ assertParsable("/jcr:root/some[1]", pathExpr(axisStep(nameTest("jcr", "root")), axisStep(nameTest("some"), literal("1"))));
+ assertParsable("/jcr:root/element(*)", pathExpr(axisStep(nameTest("jcr", "root")), axisStep(element(wildcard(),
+ wildcard()))));
+ assertParsable("/jcr:root/element(name)", pathExpr(axisStep(nameTest("jcr", "root")), axisStep(element(nameTest("name"),
+ wildcard()))));
+ assertParsable("/jcr:root/element(*, *)", pathExpr(axisStep(nameTest("jcr", "root")), axisStep(element(wildcard(),
+ wildcard()))));
+ assertParsable("/jcr:root/element(*, my:type)", pathExpr(axisStep(nameTest("jcr", "root")),
+ axisStep(element(wildcard(), nameTest("my", "type")))));
+ assertParsable("/jcr:root/element(ex:name, my:type)",
+ pathExpr(axisStep(nameTest("jcr", "root")), axisStep(element(nameTest("ex", "name"),
+ nameTest("my", "type")))));
+ assertParsable("/jcr:root/element(name, my:type)", pathExpr(axisStep(nameTest("jcr", "root")),
+ axisStep(element(nameTest("name"), nameTest("my", "type")))));
+ assertParsable("/jcr:root/element(name, type)", pathExpr(axisStep(nameTest("jcr", "root")),
+ axisStep(element(nameTest("name"), nameTest("type")))));
+ assertParsable("/jcr:root/some[1]/element(nodes, my:type)[1]", pathExpr(axisStep(nameTest("jcr", "root")),
+ axisStep(nameTest("some"), literal("1")),
+ axisStep(element(nameTest("nodes"),
+ nameTest("my", "type")),
+ literal("1"))));
+ assertParsable("/jcr:root/some[1]/element(*, my:type)[1]", pathExpr(axisStep(nameTest("jcr", "root")),
+ axisStep(nameTest("some"), literal("1")),
+ axisStep(element(wildcard(), nameTest("my", "type")),
+ literal("1"))));
+ }
+
+ @Ignore
+ @Test
public void shouldParseXPathExpressionsThatCombineSeparateExpressions() {
- assertParsable("/jcr:root/a/b/c and /jcr:root/c/d/e");
- assertParsable("/jcr:root/a/b/c and /jcr:root/c/d/e or /jcr:root/f/g/h");
+ assertParsable("/jcr:root/a/b/c union /jcr:root/c/d/e");
+ assertParsable("/jcr:root/a/b/c union /jcr:root/c/d/e intersect /jcr:root/f/g/h");
}
@Test
@@ -116,16 +159,14 @@
@Test
public void shouldParsePathExpressionWithAbbreviatedDescendantOrSelfWithRelativeNamePathPredicate() {
- assertThat(parser.parsePathExpr(tokenize("//.[c]")), is(pathExpr(descendantOrSelf(),
- filterStep(contextItem(),
- relativePathExpr(axisStep(nameTest("c")))))));
+ assertThat(parser.parsePathExpr(tokenize("//.[c]")), is(pathExpr(descendantOrSelf(), filterStep(contextItem(),
+ nameTest("c")))));
}
@Test
public void shouldParsePathExpressionWithAbbreviatedDescendantOrSelfWithRelativeNumericLiteralPredicate() {
- assertThat(parser.parsePathExpr(tokenize("//.[3]")), is(pathExpr(descendantOrSelf(),
- filterStep(contextItem(),
- relativePathExpr(filterStep(literal("3")))))));
+ assertThat(parser.parsePathExpr(tokenize("//.[3]")), is(pathExpr(descendantOrSelf(), filterStep(contextItem(),
+ literal("3")))));
}
// ----------------------------------------------------------------------------------------------------------------
@@ -148,17 +189,13 @@
@Test
public void shouldParseRelativePathExpressionWithAbbreviatedDescendantOrSelfWithRelativeNamePathPredicate() {
assertThat(parser.parseRelativePathExpr(tokenize("a//.[c]")),
- is(relativePathExpr(axisStep(nameTest("a")),
- descendantOrSelf(),
- filterStep(contextItem(), relativePathExpr(axisStep(nameTest("c")))))));
+ is(relativePathExpr(axisStep(nameTest("a")), descendantOrSelf(), filterStep(contextItem(), nameTest("c")))));
}
@Test
public void shouldParseRelativePathExpressionWithAbbreviatedDescendantOrSelfWithRelativeNumericLiteralPredicate() {
assertThat(parser.parseRelativePathExpr(tokenize("a//.[3]")),
- is(relativePathExpr(axisStep(nameTest("a")),
- descendantOrSelf(),
- filterStep(contextItem(), relativePathExpr(filterStep(literal("3")))))));
+ is(relativePathExpr(axisStep(nameTest("a")), descendantOrSelf(), filterStep(contextItem(), literal("3")))));
}
// ----------------------------------------------------------------------------------------------------------------
@@ -167,8 +204,7 @@
@Test
public void shouldParseStepExpressionFromParenthesizedLiteral() {
- assertThat(parser.parseStepExpr(tokenize("('foo')")),
- is((StepExpression)filterStep(paren(relativePathExpr(filterStep(literal("foo")))))));
+ assertThat(parser.parseStepExpr(tokenize("('foo')")), is((StepExpression)filterStep(paren(literal("foo")))));
}
@Test
@@ -178,22 +214,20 @@
@Test
public void shouldParseStepExpressionFromFunctionCallWithUnqualifiedName() {
- assertThat(parser.parseStepExpr(tokenize("element(*,*)")),
- is((StepExpression)filterStep(functionCall(nameTest("element"),
- relativePathExpr(axisStep(wildcard())),
- relativePathExpr(axisStep(wildcard()))))));
+ assertThat(parser.parseStepExpr(tokenize("element2(*,*)")),
+ is((StepExpression)filterStep(functionCall(nameTest("element2"), wildcard(), wildcard()))));
}
@Test
public void shouldParseStepExpressionFromFunctionCallWithQualifiedName() {
assertThat(parser.parseStepExpr(tokenize("foo:bar(*)")),
- is((StepExpression)filterStep(functionCall(nameTest("foo", "bar"), relativePathExpr(axisStep(wildcard()))))));
+ is((StepExpression)filterStep(functionCall(nameTest("foo", "bar"), wildcard()))));
}
@Test
public void shouldParseStepExpressionFromQualifiedNameWithPredicate() {
assertThat(parser.parseStepExpr(tokenize("foo:bar[3]")),
- is((StepExpression)axisStep(nameTest("foo", "bar"), relativePathExpr(filterStep(literal("3"))))));
+ is((StepExpression)axisStep(nameTest("foo", "bar"), literal("3"))));
}
// ----------------------------------------------------------------------------------------------------------------
@@ -255,18 +289,17 @@
@Test
public void shouldParseAxisStepFromWildcardPrefixAndNonWildcardLocalNameWithPredicates() {
- assertThat(parser.parseAxisStep(tokenize("*:name[3]")), is(axisStep(nameTest(null, "name"),
- relativePathExpr(filterStep(literal("3"))))));
+ assertThat(parser.parseAxisStep(tokenize("*:name[3]")), is(axisStep(nameTest(null, "name"), literal("3"))));
}
@Test
public void shouldParseAxisStepFromWildcardLocalNameWithPredicates() {
- assertThat(parser.parseAxisStep(tokenize("*[3]")), is(axisStep(wildcard(), relativePathExpr(filterStep(literal("3"))))));
+ assertThat(parser.parseAxisStep(tokenize("*[3]")), is(axisStep(wildcard(), literal("3"))));
}
@Test
public void shouldParseAxisStepFromWildcardPrefixAndLocalNameWithPredicates() {
- assertThat(parser.parseAxisStep(tokenize("*:*[3]")), is(axisStep(wildcard(), relativePathExpr(filterStep(literal("3"))))));
+ assertThat(parser.parseAxisStep(tokenize("*:*[3]")), is(axisStep(wildcard(), literal("3"))));
}
// ----------------------------------------------------------------------------------------------------------------
@@ -342,16 +375,63 @@
// ----------------------------------------------------------------------------------------------------------------
@Test
+ public void shouldParsePredicatesWithAttributeEqualsStringLiteral() {
+ assertThat(parser.parsePredicates(tokenize("[@jcr:title='something']")),
+ is(predicates(comparison(attributeNameTest(nameTest("jcr", "title")), Operator.EQUAL_TO, literal("something")))));
+ }
+
+ @Test
+ public void shouldParsePredicatesWithAttributeLessThanIntegerLiteral() {
+ assertThat(parser.parsePredicates(tokenize("[@ex:age<3]")), is(predicates(comparison(attributeNameTest(nameTest("ex",
+ "age")),
+ Operator.LESS_THAN,
+ literal("3")))));
+ }
+
+ @Test
+ public void shouldParsePredicatesWithAttributeLikeStringLiteral() {
+ assertThat(parser.parsePredicates(tokenize("[jcr:like(@jcr:title,'%something%')]")),
+ is(predicates(functionCall(nameTest("jcr", "like"),
+ attributeNameTest(nameTest("jcr", "title")),
+ literal("%something%")))));
+ }
+
+ @Test
+ public void shouldParsePredicatesWithAndedExpressions() {
+ assertThat(parser.parsePredicates(tokenize("[@ex:age<3 and jcr:like(@jcr:title,'%something%')]")),
+ is(predicates(and(comparison(attributeNameTest(nameTest("ex", "age")), Operator.LESS_THAN, literal("3")),
+ functionCall(nameTest("jcr", "like"),
+ attributeNameTest(nameTest("jcr", "title")),
+ literal("%something%"))))));
+ }
+
+ @Test
+ public void shouldParsePredicatesWithOredExpressions() {
+ assertThat(parser.parsePredicates(tokenize("[@ex:age<3 or jcr:like(@jcr:title,'%something%')]")),
+ is(predicates(or(comparison(attributeNameTest(nameTest("ex", "age")), Operator.LESS_THAN, literal("3")),
+ functionCall(nameTest("jcr", "like"),
+ attributeNameTest(nameTest("jcr", "title")),
+ literal("%something%"))))));
+ }
+
+ @Test
+ public void shouldParsePredicatesWithMultipleSeparatePredicates() {
+ assertThat(parser.parsePredicates(tokenize("[@ex:age<3][jcr:like(@jcr:title,'%something%')]")),
+ is(predicates(comparison(attributeNameTest(nameTest("ex", "age")), Operator.LESS_THAN, literal("3")),
+ functionCall(nameTest("jcr", "like"),
+ attributeNameTest(nameTest("jcr", "title")),
+ literal("%something%")))));
+ }
+
+ @Test
public void shouldParsePredicatesWhenThereIsOnlyOnePredicate() {
- assertThat(parser.parsePredicates(tokenize("[foo]")), is(predicates(relativePathExpr(axisStep(nameTest("foo"))))));
+ assertThat(parser.parsePredicates(tokenize("[foo]")), is(predicates(nameTest("foo"))));
}
@Test
public void shouldParsePredicatesWhenThereAreMultiplePredicates() {
- assertThat(parser.parsePredicates(tokenize("['foo']['bar']")),
- is(predicates(relativePathExpr(filterStep(literal("foo"))), relativePathExpr(filterStep(literal("bar"))))));
- assertThat(parser.parsePredicates(tokenize("[foo][bar]")), is(predicates(relativePathExpr(axisStep(nameTest("foo"))),
- relativePathExpr(axisStep(nameTest("bar"))))));
+ assertThat(parser.parsePredicates(tokenize("['foo']['bar']")), is(predicates(literal("foo"), literal("bar"))));
+ assertThat(parser.parsePredicates(tokenize("[foo][bar]")), is(predicates(nameTest("foo"), nameTest("bar"))));
}
// ----------------------------------------------------------------------------------------------------------------
@@ -369,7 +449,7 @@
@Test
public void shouldParseParenthesizedExpression() {
- assertThat(parser.parseParenthesizedExpr(tokenize("('foo')")), is(paren(relativePathExpr(filterStep(literal("foo"))))));
+ assertThat(parser.parseParenthesizedExpr(tokenize("('foo')")), is(paren(literal("foo"))));
}
// ----------------------------------------------------------------------------------------------------------------
@@ -430,7 +510,7 @@
assertThat(func, is(notNullValue()));
assertThat(func.getName(), is(nameTest("a")));
assertThat(func.getParameters().size(), is(1));
- assertThat(func.getParameters().get(0), is((Component)relativePathExpr(filterStep(literal("foo")))));
+ assertThat(func.getParameters().get(0), is((Component)literal("foo")));
}
@Test
@@ -439,7 +519,7 @@
assertThat(func, is(notNullValue()));
assertThat(func.getName(), is(nameTest("a")));
assertThat(func.getParameters().size(), is(1));
- assertThat(func.getParameters().get(0), is((Component)relativePathExpr(axisStep(nameTest("foo")))));
+ assertThat(func.getParameters().get(0), is((Component)nameTest("foo")));
}
// ----------------------------------------------------------------------------------------------------------------
@@ -557,7 +637,7 @@
@Test
public void shouldParseAnyKindTest() {
- assertThat(parser.parseAnyKindTest(tokenize("node()")), is(notNullValue()));
+ assertThat(parser.parseAnyKindTest(tokenize("node()")), is(instanceOf(AnyKindTest.class)));
}
@Test
@@ -573,7 +653,7 @@
@Test
public void shouldParseCommentTest() {
- assertThat(parser.parseCommentTest(tokenize("comment()")), is(notNullValue()));
+ assertThat(parser.parseCommentTest(tokenize("comment()")), is(instanceOf(CommentTest.class)));
}
@Test
@@ -589,7 +669,7 @@
@Test
public void shouldParseTextTest() {
- assertThat(parser.parseTextTest(tokenize("text()")), is(notNullValue()));
+ assertThat(parser.parseTextTest(tokenize("text()")), is(instanceOf(TextTest.class)));
}
@Test
@@ -769,8 +849,12 @@
assertThat(result, is(nullValue()));
}
+ // ----------------------------------------------------------------------------------------------------------------
+ // utility methods
+ // ----------------------------------------------------------------------------------------------------------------
+
protected TokenStream tokenize( String xpath ) {
- Tokenizer tokenizer = new XPathTokenizer(false); // skip comments
+ Tokenizer tokenizer = new XPathParser.XPathTokenizer(false); // skip comments
return new TokenStream(xpath, tokenizer, true).start(); // case sensitive!!
}
@@ -812,6 +896,22 @@
return new ContextItem();
}
+ protected And and( Component left,
+ Component right ) {
+ return new And(left, right);
+ }
+
+ protected Or or( Component left,
+ Component right ) {
+ return new Or(left, right);
+ }
+
+ protected Comparison comparison( Component left,
+ Operator operator,
+ Component right ) {
+ return new Comparison(left, operator, right);
+ }
+
protected List<Component> predicates( Component... predicates ) {
return Arrays.asList(predicates);
}
@@ -833,6 +933,15 @@
return new AttributeTest(name, type);
}
+ protected ElementTest element( NameTest name ) {
+ return new ElementTest(name, null);
+ }
+
+ protected ElementTest element( NameTest name,
+ NameTest type ) {
+ return new ElementTest(name, type);
+ }
+
protected FunctionCall functionCall( NameTest name,
Component... parameters ) {
return new FunctionCall(name, Arrays.asList(parameters));
@@ -852,12 +961,22 @@
}
protected void assertParsable( String xpath ) {
- new XPathParser().parseQuery(xpath, context);
+ new XPathQueryParser().parseQuery(xpath, context);
}
+ protected void assertParsable( String xpath,
+ Component component ) {
+ Component actual = parser.parseExpr(tokenize(xpath));
+ if (component != null) {
+ assertThat(actual, is(component));
+ } else {
+ assertThat(actual, is(nullValue()));
+ }
+ }
+
protected void assertNotParsable( String xpath ) {
try {
- new XPathParser().parseQuery(xpath, context);
+ new XPathQueryParser().parseQuery(xpath, context);
fail("Expected an invalid XPath: " + xpath);
} catch (ParsingException e) {
// expected
Added: trunk/dna-jcr/src/test/java/org/jboss/dna/jcr/xpath/XPathToQueryTranslatorTest.java
===================================================================
--- trunk/dna-jcr/src/test/java/org/jboss/dna/jcr/xpath/XPathToQueryTranslatorTest.java (rev 0)
+++ trunk/dna-jcr/src/test/java/org/jboss/dna/jcr/xpath/XPathToQueryTranslatorTest.java 2009-10-03 04:09:29 UTC (rev 1286)
@@ -0,0 +1,297 @@
+/*
+ * JBoss DNA (http://www.jboss.org/dna)
+ * 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.
+ * See the AUTHORS.txt file in the distribution for a full listing of
+ * individual contributors.
+ *
+ * JBoss DNA is free software. Unless otherwise indicated, all code in JBoss DNA
+ * is licensed to you 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.
+ *
+ * JBoss DNA 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 software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.dna.jcr.xpath;
+
+import static org.hamcrest.core.Is.is;
+import static org.junit.Assert.assertThat;
+import org.hamcrest.Matcher;
+import org.jboss.dna.graph.ExecutionContext;
+import org.jboss.dna.graph.query.model.QueryCommand;
+import org.jboss.dna.graph.query.parse.SqlQueryParser;
+import org.jboss.dna.jcr.xpath.XPath.Component;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ *
+ */
+public class XPathToQueryTranslatorTest {
+
+ private ExecutionContext context;
+ private XPathParser parser;
+
+ @Before
+ public void beforeEach() {
+ context = new ExecutionContext();
+ context.getNamespaceRegistry().register("x", "http://example.com");
+ parser = new XPathParser(context);
+ }
+
+ @After
+ public void afterEach() {
+ parser = null;
+ }
+
+ @Test
+ public void shouldTranslateXPathExpressionsToSql() {
+ printSqlFor("//element(*,my:type)");
+ printSqlFor("//element(nodeName,my:type)");
+ }
+
+ @Test
+ public void shouldTranslateFromXPathOfAnyNode() {
+ assertThat(xpath("//element(*)"), isSql("SELECT * FROM __ALLNODES__ AS nodeSet1"));
+ assertThat(xpath("/jcr:root//element(*)"), isSql("SELECT * FROM __ALLNODES__ AS nodeSet1"));
+ assertThat(xpath("//*"), isSql("SELECT * FROM __ALLNODES__ AS nodeSet1"));
+ assertThat(xpath("/jcr:root//*"), isSql("SELECT * FROM __ALLNODES__ AS nodeSet1"));
+ assertThat(xpath("//."), isSql("SELECT * FROM __ALLNODES__ AS nodeSet1"));
+ assertThat(xpath("/jcr:root//."), isSql("SELECT * FROM __ALLNODES__ AS nodeSet1"));
+ }
+
+ @Test
+ public void shouldTranslateFromXPathContainingExplicitPath() {
+ assertThat(xpath("/jcr:root/a"),
+ isSql("SELECT * FROM __ALLNODES__ AS nodeSet1 WHERE NAME(nodeSet1) = 'a' AND DEPTH(nodeSet1) = 1"));
+ assertThat(xpath("/jcr:root/a/b"), isSql("SELECT * FROM __ALLNODES__ AS nodeSet1 WHERE PATH(nodeSet1) = '/a/b'"));
+ assertThat(xpath("/jcr:root/a/b/c"), isSql("SELECT * FROM __ALLNODES__ AS nodeSet1 WHERE PATH(nodeSet1) = '/a/b/c'"));
+ assertThat(xpath("/jcr:root/a/b/c/d"), isSql("SELECT * FROM __ALLNODES__ AS nodeSet1 WHERE PATH(nodeSet1) = '/a/b/c/d'"));
+ }
+
+ @Test
+ public void shouldTranslateFromXPathContainingExplicitPathWithChildNumbers() {
+ assertThat(xpath("/jcr:root/a[2]/b"), isSql("SELECT * FROM __ALLNODES__ AS nodeSet1 WHERE PATH(nodeSet1) = '/a[2]/b'"));
+ assertThat(xpath("/jcr:root/a/b[3]"), isSql("SELECT * FROM __ALLNODES__ AS nodeSet1 WHERE PATH(nodeSet1) = '/a/b[3]'"));
+ assertThat(xpath("/jcr:root/a[2]/b[3]"),
+ isSql("SELECT * FROM __ALLNODES__ AS nodeSet1 WHERE PATH(nodeSet1) = '/a[2]/b[3]'"));
+ }
+
+ @Test
+ public void shouldTranslateFromXPathContainingExplicitPathWithWildcardChildNumbers() {
+ assertThat(xpath("/jcr:root/a[*]/b"), isSql("SELECT * FROM __ALLNODES__ AS nodeSet1 WHERE PATH(nodeSet1) = '/a/b'"));
+ assertThat(xpath("/jcr:root/a/b[*]"), isSql("SELECT * FROM __ALLNODES__ AS nodeSet1 WHERE PATH(nodeSet1) = '/a/b'"));
+ assertThat(xpath("/jcr:root/a[*]/b[*]"), isSql("SELECT * FROM __ALLNODES__ AS nodeSet1 WHERE PATH(nodeSet1) = '/a/b'"));
+ }
+
+ @Test
+ public void shouldTranslateFromXPathContainingPathWithDescendantOrSelf() {
+ assertThat(xpath("/jcr:root/a/b//c"),
+ isSql("SELECT * FROM __ALLNODES__ AS nodeSet1 WHERE PATH(nodeSet1) = '/a/b/c' OR PATH(nodeSet1) LIKE '/a/b/%/c'"));
+ assertThat(xpath("/jcr:root/a/b[2]//c"),
+ isSql("SELECT * FROM __ALLNODES__ AS nodeSet1 WHERE PATH(nodeSet1) = '/a/b[2]/c' OR PATH(nodeSet1) LIKE '/a/b[2]/%/c'"));
+ assertThat(xpath("/jcr:root/a/b//c[4]"),
+ isSql("SELECT * FROM __ALLNODES__ AS nodeSet1 WHERE PATH(nodeSet1) = '/a/b/c[4]' OR PATH(nodeSet1) LIKE '/a/b/%/c[4]'"));
+ assertThat(xpath("/jcr:root/a/b[2]//c[4]"),
+ isSql("SELECT * FROM __ALLNODES__ AS nodeSet1 WHERE PATH(nodeSet1) = '/a/b[2]/c[4]' OR PATH(nodeSet1) LIKE '/a/b[2]/%/c[4]'"));
+ }
+
+ @Test
+ public void shouldTranslateFromXPathContainingPathWithMultipleDescendantOrSelf() {
+ assertThat(xpath("/jcr:root/a/b//c//d"),
+ isSql("SELECT * FROM __ALLNODES__ AS nodeSet1 WHERE (((PATH(nodeSet1) = '/a/b/c/d' OR PATH(nodeSet1) LIKE '/a/b/%/c/d') OR PATH(nodeSet1) LIKE '/a/b/c/%/d') OR PATH(nodeSet1) LIKE '/a/b/%/c/%/d')"));
+ }
+
+ @Test
+ public void shouldTranslateFromXPathContainingPredicatesUsingRelativePaths() {
+ assertThat(xpath("//element(*,my:type)[a/@id]"),
+ isSql("SELECT * FROM [my:type] JOIN __ALLNODES__ as nodeSet1 ON ISCHILDNODE(nodeSet1,[my:type]) WHERE NAME(nodeSet1) = 'a' AND nodeSet1.id IS NOT NULL"));
+ assertThat(xpath("//element(*,my:type)[a/b/@id]"),
+ isSql("SELECT * FROM [my:type] JOIN __ALLNODES__ as nodeSet1 ON ISCHILDNODE(nodeSet1,[my:type]) JOIN __ALLNODES__ as nodeSet2 ON ISCHILDNODE(nodeSet2,nodeSet1) WHERE (NAME(nodeSet1) = 'a' AND NAME(nodeSet2) = 'b') AND nodeSet2.id IS NOT NULL"));
+ assertThat(xpath("//element(*,my:type)[a/b/((@id and @name) or not(@address))]"),
+ isSql("SELECT * FROM [my:type] JOIN __ALLNODES__ as nodeSet1 ON ISCHILDNODE(nodeSet1,[my:type]) JOIN __ALLNODES__ as nodeSet2 ON ISCHILDNODE(nodeSet2,nodeSet1) WHERE (NAME(nodeSet1) = 'a' AND NAME(nodeSet2) = 'b') AND ((nodeSet2.id IS NOT NULL and nodeSet2.name IS NOT NULL) OR (NOT(nodeSet2.address IS NOT NULL)))"));
+ assertThat(xpath("//element(*,my:type)[./a/b/((@id and @name) or not(@address))]"),
+ isSql("SELECT * FROM [my:type] JOIN __ALLNODES__ as nodeSet1 ON ISCHILDNODE(nodeSet1,[my:type]) JOIN __ALLNODES__ as nodeSet2 ON ISCHILDNODE(nodeSet2,nodeSet1) WHERE (NAME(nodeSet1) = 'a' AND NAME(nodeSet2) = 'b') AND ((nodeSet2.id IS NOT NULL and nodeSet2.name IS NOT NULL) OR (NOT(nodeSet2.address IS NOT NULL)))"));
+ assertThat(xpath("//element(*,my:type)[a/b/((@id and @name) or not(jcr:contains(@desc,'rock star')))]"),
+ isSql("SELECT * FROM [my:type] JOIN __ALLNODES__ as nodeSet1 ON ISCHILDNODE(nodeSet1,[my:type]) JOIN __ALLNODES__ as nodeSet2 ON ISCHILDNODE(nodeSet2,nodeSet1) WHERE (NAME(nodeSet1) = 'a' AND NAME(nodeSet2) = 'b') AND ((nodeSet2.id IS NOT NULL and nodeSet2.name IS NOT NULL) OR (NOT(CONTAINS(nodeSet2.desc,'rock star'))))"));
+ assertThat(xpath("//element(*,my:type)[*/@id]"),
+ isSql("SELECT * FROM [my:type] JOIN __ALLNODES__ as nodeSet1 ON ISCHILDNODE(nodeSet1,[my:type]) WHERE nodeSet1.id IS NOT NULL"));
+ assertThat(xpath("//element(*,my:type)[*/*/@id]"),
+ isSql("SELECT * FROM [my:type] JOIN __ALLNODES__ as nodeSet1 ON ISCHILDNODE(nodeSet1,[my:type]) JOIN __ALLNODES__ as nodeSet2 ON ISCHILDNODE(nodeSet2,nodeSet1) WHERE nodeSet2.id IS NOT NULL"));
+ assertThat(xpath("//element(*,my:type)[./*/*/@id]"),
+ isSql("SELECT * FROM [my:type] JOIN __ALLNODES__ as nodeSet1 ON ISCHILDNODE(nodeSet1,[my:type]) JOIN __ALLNODES__ as nodeSet2 ON ISCHILDNODE(nodeSet2,nodeSet1) WHERE nodeSet2.id IS NOT NULL"));
+ assertThat(xpath("//element(*,my:type)[.//@id]"),
+ isSql("SELECT * FROM [my:type] JOIN __ALLNODES__ as nodeSet1 ON ISDESCENDANTNODE(nodeSet1,[my:type]) WHERE nodeSet1.id IS NOT NULL"));
+ }
+
+ @Test
+ public void shouldTranslateFromXPathContainingPredicatesIdentifyingPropertiesThatMustHaveValues() {
+ assertThat(xpath("//element(*,my:type)[@id]"), isSql("SELECT * FROM [my:type] WHERE id IS NOT NULL"));
+ assertThat(xpath("//element(*,my:type)[@id][@name]"),
+ isSql("SELECT * FROM [my:type] WHERE id IS NOT NULL AND name IS NOT NULL"));
+ assertThat(xpath("//element(*,my:type)[@id | @name]"),
+ isSql("SELECT * FROM [my:type] WHERE id IS NOT NULL OR name IS NOT NULL"));
+ assertThat(xpath("//element(*,my:type)[@id | (@name and @address)]"),
+ isSql("SELECT * FROM [my:type] WHERE id IS NOT NULL OR (name IS NOT NULL AND address IS NOT NULL)"));
+ }
+
+ @Test
+ public void shouldTranslateFromXPathContainingPredicatesUsingNot() {
+ assertThat(xpath("//element(*,my:type)[not(@id)]"), isSql("SELECT * FROM [my:type] WHERE NOT(id IS NOT NULL)"));
+ assertThat(xpath("//element(*,my:type)[not(jcr:contains(@desc,'rock star'))]"),
+ isSql("SELECT * FROM [my:type] WHERE NOT(CONTAINS(desc,'rock star'))"));
+ assertThat(xpath("//element(*,my:type)[not(@id < 1 and jcr:contains(@desc,'rock star'))]"),
+ isSql("SELECT * FROM [my:type] WHERE NOT(id < 1 AND CONTAINS(desc,'rock star'))"));
+ }
+
+ @Test
+ public void shouldTranslateFromXPathContainingPredicatesIdentifyingPropertyCriteria() {
+ assertThat(xpath("//element(*,my:type)[@id = 1]"), isSql("SELECT * FROM [my:type] WHERE id = 1"));
+ assertThat(xpath("//element(*,my:type)[@id < 1 and @name = 'john']"),
+ isSql("SELECT * FROM [my:type] WHERE id < 1 AND name = 'john'"));
+ assertThat(xpath("//element(*,my:type)[@id < 1 and ( @name = 'john' or @name = 'mary')]"),
+ isSql("SELECT * FROM [my:type] WHERE id < 1 AND (name = 'john' OR name = 'mary')"));
+ assertThat(xpath("//element(*,my:type)[@id < 1 and ( jcr:like(@name,'%john') or @name = 'mary')]"),
+ isSql("SELECT * FROM [my:type] WHERE id < 1 AND (name like '%john' OR name = 'mary')"));
+ assertThat(xpath("//element(*,my:type)[@id < 1 and jcr:contains(@desc,'rock star')]"),
+ isSql("SELECT * FROM [my:type] WHERE id < 1 AND CONTAINS(desc,'rock star')"));
+ }
+
+ @Test
+ public void shouldTranslateFromXPathContainingPredicatesIdentifyingPropertyCriteriaWithTypeCasts() {
+ assertThat(xpath("//element(*,my:type)[@datestart<=xs:dateTime('2009-09-24T11:53:23.293-05:00')]"),
+ isSql("SELECT * FROM [my:type] WHERE datestart <= CAST('2009-09-24T11:53:23.293-05:00' AS DATE)"));
+ assertThat(xpath("//element(*,my:type)[@prop<=xs:boolean('true')]"),
+ isSql("SELECT * FROM [my:type] WHERE prop <= CAST('true' AS BOOLEAN)"));
+ }
+
+ @Test
+ public void shouldTranslateFromXPathContainingAttributesInPathIdentifyingPropertiesToBeSelected() {
+ assertThat(xpath("//element(*,my:type)/@id"), isSql("SELECT id FROM [my:type]"));
+ assertThat(xpath("//element(*,my:type)/(@id|@name)"), isSql("SELECT id, name FROM [my:type]"));
+ assertThat(xpath("//element(*,my:type)/(@id|@x:address)"), isSql("SELECT id, [x:address] FROM [my:type]"));
+ assertThat(xpath("//element(*,my:type)/(@id|@name|@x:address)"), isSql("SELECT id, name, [x:address] FROM [my:type]"));
+ assertThat(xpath("//element(*,my:type)/(@id union @name)"), isSql("SELECT id, name FROM [my:type]"));
+ assertThat(xpath("//element(*,my:type)/(@id union @name union @x:address)"),
+ isSql("SELECT id, name, [x:address] FROM [my:type]"));
+ assertThat(xpath("//(@id|@name)"), isSql("SELECT nodeSet1.id, nodeSet1.name FROM __ALLNODES__ AS nodeSet1"));
+ assertThat(xpath("//./(@id|@name)"), isSql("SELECT nodeSet1.id, nodeSet1.name FROM __ALLNODES__ AS nodeSet1"));
+ }
+
+ @Test
+ public void shouldTranslateFromXPathOfAnyNodeOfSpecificType() {
+ assertThat(xpath("//element(*,my:type)"), isSql("SELECT * FROM [my:type]"));
+ }
+
+ @Test
+ public void shouldTranslateFromXPathOfAnyNodeOfSpecificTypeAndWithSpecificName() {
+ assertThat(xpath("//element(nodeName,my:type)"), isSql("SELECT * FROM [my:type] WHERE NAME([my:type]) = 'nodeName'"));
+ }
+
+ @Test
+ public void shouldTranslateFromXPathOfAnyNodeWithName() {
+ assertThat(xpath("//element(nodeName,*)"),
+ isSql("SELECT * FROM __ALLNODES__ AS nodeSet1 WHERE NAME(nodeSet1) = 'nodeName'"));
+
+ assertThat(xpath("//element(nodeName,*)"),
+ isSql("SELECT * FROM __ALLNODES__ AS nodeSet1 WHERE NAME(nodeSet1) = 'nodeName'"));
+
+ assertThat(xpath("//nodeName"), isSql("SELECT * FROM __ALLNODES__ AS nodeSet1 WHERE NAME(nodeSet1) = 'nodeName'"));
+
+ assertThat(xpath("/jcr:root//element(nodeName,*)"),
+ isSql("SELECT * FROM __ALLNODES__ AS nodeSet1 WHERE NAME(nodeSet1) = 'nodeName'"));
+
+ assertThat(xpath("/jcr:root//nodeName"),
+ isSql("SELECT * FROM __ALLNODES__ AS nodeSet1 WHERE NAME(nodeSet1) = 'nodeName'"));
+ }
+
+ @Test
+ public void shouldTranslateFromXPathOfNodeWithNameUnderRoot() {
+ assertThat(xpath("/jcr:root/element(nodeName,*)"),
+ isSql("SELECT * FROM __ALLNODES__ AS nodeSet1 WHERE NAME(nodeSet1) = 'nodeName' AND DEPTH(nodeSet1) = 1"));
+
+ assertThat(xpath("/jcr:root/nodeName"),
+ isSql("SELECT * FROM __ALLNODES__ AS nodeSet1 WHERE NAME(nodeSet1) = 'nodeName' AND DEPTH(nodeSet1) = 1"));
+
+ assertThat(xpath("nodeName"),
+ isSql("SELECT * FROM __ALLNODES__ AS nodeSet1 WHERE NAME(nodeSet1) = 'nodeName' AND DEPTH(nodeSet1) = 1"));
+ }
+
+ @Test
+ public void shouldTranslateFromXPathOfAnyNodeUsingPredicate() {
+ assertThat(xpath("//.[jcr:contains(.,'bar')]"),
+ isSql("SELECT * FROM __ALLNODES__ AS nodeSet1 WHERE CONTAINS(nodeSet1.*,'bar')"));
+ assertThat(xpath("//.[jcr:contains(a,'bar')]"),
+ isSql("SELECT * FROM __ALLNODES__ AS nodeSet1 JOIN __ALLNODES__ AS nodeSet2 ON ISCHILDNODE(nodeSet2,nodeSet1) WHERE CONTAINS(nodeSet2.*,'bar')"));
+ assertThat(xpath("//*[jcr:contains(.,'bar')]"),
+ isSql("SELECT * FROM __ALLNODES__ AS nodeSet1 WHERE CONTAINS(nodeSet1.*,'bar')"));
+ assertThat(xpath("//*[jcr:contains(a,'bar')]"),
+ isSql("SELECT * FROM __ALLNODES__ AS nodeSet1 JOIN __ALLNODES__ AS nodeSet2 ON ISCHILDNODE(nodeSet2,nodeSet1) WHERE CONTAINS(nodeSet2.*,'bar')"));
+ assertThat(xpath("//*[jcr:contains(a/@b,'bar')]"),
+ isSql("SELECT * FROM __ALLNODES__ AS nodeSet1 JOIN __ALLNODES__ AS nodeSet2 ON ISCHILDNODE(nodeSet2,nodeSet1) WHERE NAME(nodeSet2) = 'a' AND CONTAINS(nodeSet2.b,'bar')"));
+ assertThat(xpath("//*[jcr:contains(a/*/@b,'bar')]"),
+ isSql("SELECT * FROM __ALLNODES__ AS nodeSet1 JOIN __ALLNODES__ AS nodeSet2 ON ISCHILDNODE(nodeSet2,nodeSet1) JOIN __ALLNODES__ AS nodeSet3 ON ISCHILDNODE(nodeSet3,nodeSet2) WHERE NAME(nodeSet2) = 'a' AND CONTAINS(nodeSet3.b,'bar')"));
+ assertThat(xpath("/jcr:root//element(*)[jcr:contains(a/@b,'bar')]"),
+ isSql("SELECT * FROM __ALLNODES__ AS nodeSet1 JOIN __ALLNODES__ AS nodeSet2 ON ISCHILDNODE(nodeSet2,nodeSet1) WHERE NAME(nodeSet2) = 'a' AND CONTAINS(nodeSet2.b,'bar')"));
+ assertThat(xpath("/jcr:root//element(*)[jcr:contains(a/*/@b,'bar')]"),
+ isSql("SELECT * FROM __ALLNODES__ AS nodeSet1 JOIN __ALLNODES__ AS nodeSet2 ON ISCHILDNODE(nodeSet2,nodeSet1) JOIN __ALLNODES__ AS nodeSet3 ON ISCHILDNODE(nodeSet3,nodeSet2) WHERE NAME(nodeSet2) = 'a' AND CONTAINS(nodeSet3.b,'bar')"));
+ assertThat(xpath("/jcr:root//*[jcr:contains(a/@b,'bar')]"),
+ isSql("SELECT * FROM __ALLNODES__ AS nodeSet1 JOIN __ALLNODES__ AS nodeSet2 ON ISCHILDNODE(nodeSet2,nodeSet1) WHERE NAME(nodeSet2) = 'a' AND CONTAINS(nodeSet2.b,'bar')"));
+ assertThat(xpath("/jcr:root//*[jcr:contains(a/*/@b,'bar')]"),
+ isSql("SELECT * FROM __ALLNODES__ AS nodeSet1 JOIN __ALLNODES__ AS nodeSet2 ON ISCHILDNODE(nodeSet2,nodeSet1) JOIN __ALLNODES__ AS nodeSet3 ON ISCHILDNODE(nodeSet3,nodeSet2) WHERE NAME(nodeSet2) = 'a' AND CONTAINS(nodeSet3.b,'bar')"));
+ }
+
+ // @Test
+ // public void shouldParseXPathExpressions() {
+ // assertParsable("/jcr:root/a/b/c");
+ // assertParsable("/jcr:root/a/b/c[*]");
+ // assertParsable("/jcr:root/some[1]/element(nodes, my:type)[1]");
+ // assertParsable("//element(*,my:type)");
+ // assertParsable("//element(*,my:type)[@jcr:title='something' and @globalProperty='something else']");
+ // assertParsable("//element(*,my:type)[@jcr:title | @globalProperty]");
+ // assertParsable("//element(*, my:type) order by @my:title");
+ // assertParsable("//element(*, my:type) [jcr:contains(., 'jcr')] order by jcr:score() descending");
+ // assertParsable("//element(*, employee)[@secretary and @assistant]");
+ // }
+
+ // ----------------------------------------------------------------------------------------------------------------
+ // utility methods
+ // ----------------------------------------------------------------------------------------------------------------
+
+ protected void printSqlFor( String xpath ) {
+ System.out.println("XPath: " + xpath);
+ System.out.println("SQL: " + translateToSql(xpath));
+ System.out.println();
+ }
+
+ private QueryCommand translateToSql( String xpath ) {
+ Component component = parser.parseXPath(xpath);
+ XPathToQueryTranslator translator = new XPathToQueryTranslator(context, xpath);
+ return translator.createQuery(component);
+ }
+
+ private QueryCommand xpath( String xpath ) {
+ Component component = parser.parseXPath(xpath);
+ XPathToQueryTranslator translator = new XPathToQueryTranslator(context, xpath);
+ return translator.createQuery(component);
+ }
+
+ protected QueryCommand sql( String sql ) {
+ return new SqlQueryParser().parseQuery(sql, context);
+ }
+
+ protected Matcher<QueryCommand> isSql( String sql ) {
+ return is(sql(sql));
+ }
+
+}
Property changes on: trunk/dna-jcr/src/test/java/org/jboss/dna/jcr/xpath/XPathToQueryTranslatorTest.java
___________________________________________________________________
Name: svn:keywords
+ Id Revision
Name: svn:eol-style
+ LF
Modified: trunk/dna-search/src/main/java/org/jboss/dna/search/LuceneQueryEngine.java
===================================================================
--- trunk/dna-search/src/main/java/org/jboss/dna/search/LuceneQueryEngine.java 2009-10-03 04:07:41 UTC (rev 1285)
+++ trunk/dna-search/src/main/java/org/jboss/dna/search/LuceneQueryEngine.java 2009-10-03 04:09:29 UTC (rev 1286)
@@ -25,7 +25,10 @@
import java.io.IOException;
import java.util.LinkedList;
+import java.util.Set;
import org.apache.lucene.queryParser.ParseException;
+import org.jboss.dna.common.text.ParsingException;
+import org.jboss.dna.common.util.CheckArg;
import org.jboss.dna.graph.query.QueryContext;
import org.jboss.dna.graph.query.QueryEngine;
import org.jboss.dna.graph.query.QueryResults;
@@ -34,6 +37,8 @@
import org.jboss.dna.graph.query.optimize.Optimizer;
import org.jboss.dna.graph.query.optimize.OptimizerRule;
import org.jboss.dna.graph.query.optimize.RuleBasedOptimizer;
+import org.jboss.dna.graph.query.parse.InvalidQueryException;
+import org.jboss.dna.graph.query.parse.QueryParser;
import org.jboss.dna.graph.query.plan.CanonicalPlanner;
import org.jboss.dna.graph.query.plan.PlanHints;
import org.jboss.dna.graph.query.plan.PlanNode;
@@ -53,10 +58,66 @@
engine = new QueryEngine(new CanonicalPlanner(), new LuceneOptimizer(), new LuceneProcessor(), schemata);
}
+ public LuceneQueryEngine( Schemata schemata,
+ QueryParser... languages ) {
+ engine = new QueryEngine(new CanonicalPlanner(), new LuceneOptimizer(), new LuceneProcessor(), schemata, languages);
+ }
+
/**
+ * Add a language to this engine by supplying its parser.
+ *
+ * @param languageParser the query parser for the language
+ * @throws IllegalArgumentException if the language parser is null
+ */
+ public void addLanguage( QueryParser languageParser ) {
+ this.engine.addLanguage(languageParser);
+ }
+
+ /**
+ * Remove from this engine the language with the given name.
+ *
+ * @param language the name of the language, which is to match the {@link QueryParser#getLanguage() language} of the parser
+ * @return the parser for the language, or null if the engine had no support for the named language
+ * @throws IllegalArgumentException if the language is null
+ */
+ public QueryParser removeLanguage( String language ) {
+ return this.engine.removeLanguage(language);
+ }
+
+ /**
+ * Get the set of languages that this engine is capable of parsing.
+ *
+ * @return the unmodifiable copy of the set of languages; never null but possibly empty
+ */
+ public Set<String> getLanguages() {
+ return this.engine.getLanguages();
+ }
+
+ /**
* Execute the supplied query by planning, optimizing, and then processing it.
*
+ * @param indexes the context in which the query should be executed
+ * @param language the language in which the query is expressed; must be one of the supported {@link #getLanguages()
+ * languages}
* @param query the query that is to be executed
+ * @return the query results; never null
+ * @throws IllegalArgumentException if the language, context or query references are null, or if the language is not know
+ * @throws ParsingException if there is an error parsing the supplied query
+ * @throws InvalidQueryException if the supplied query can be parsed but is invalid
+ */
+ public QueryResults execute( IndexContext indexes,
+ String language,
+ String query ) {
+ CheckArg.isNotNull(language, "language");
+ CheckArg.isNotNull(indexes, "indexes");
+ CheckArg.isNotNull(query, "query");
+ return engine.execute(indexes.context(), language, query);
+ }
+
+ /**
+ * Execute the supplied query by planning, optimizing, and then processing it.
+ *
+ * @param query the query that is to be executed
* @param indexes the indexes that should be used to execute the query; never null
* @return the query results; never null
* @throws IllegalArgumentException if the context or query references are null
16 years, 7 months
DNA SVN: r1285 - in trunk: dna-jcr/src/main/java/org/jboss/dna/jcr and 3 other directories.
by dna-commits@lists.jboss.org
Author: rhauch
Date: 2009-10-03 00:07:41 -0400 (Sat, 03 Oct 2009)
New Revision: 1285
Added:
trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/xpath/
trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/xpath/XPath.java
trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/xpath/XPathParser.java
trunk/dna-jcr/src/test/java/org/jboss/dna/jcr/xpath/
trunk/dna-jcr/src/test/java/org/jboss/dna/jcr/xpath/XPathParserTest.java
Modified:
trunk/dna-common/src/main/java/org/jboss/dna/common/text/TokenStream.java
Log:
DNA-467 Added XPath parser with associated unit tests, though this doesn't yet convert the parsed XPath AST into a query using the Abstract Query Model
Modified: trunk/dna-common/src/main/java/org/jboss/dna/common/text/TokenStream.java
===================================================================
--- trunk/dna-common/src/main/java/org/jboss/dna/common/text/TokenStream.java 2009-10-02 17:35:34 UTC (rev 1284)
+++ trunk/dna-common/src/main/java/org/jboss/dna/common/text/TokenStream.java 2009-10-03 04:07:41 UTC (rev 1285)
@@ -437,7 +437,7 @@
*
* @return the current token's position; never null
* @throws IllegalStateException if this method was called before the stream was {@link #start() started}
- * @throws NoSuchElementException if there is no previous token
+ * @throws NoSuchElementException if there is no next token
*/
public Position nextPosition() {
return currentToken().position();
@@ -1047,7 +1047,7 @@
ListIterator<Token> iter = tokens.listIterator(tokenIterator.previousIndex());
if (!iter.hasNext()) return false;
Token token = iter.next();
- if (currentExpectedType != ANY_TYPE || currentToken().type() != currentExpectedType) return false;
+ if (currentExpectedType != ANY_TYPE && currentToken().type() != currentExpectedType) return false;
for (int nextExpectedType : expectedTypeForNextTokens) {
if (!iter.hasNext()) return false;
token = iter.next();
@@ -1366,6 +1366,22 @@
boolean isNextValidXmlCharacter();
/**
+ * Determine if the next character on the sream is a {@link XmlCharacters#isValidName(int) valid XML NCName character}.
+ * This method does <i>not</i> advance the stream.
+ *
+ * @return true if there is a {@link #next() next} character and it is a valid XML Name character, or false otherwise
+ */
+ boolean isNextValidXmlNameCharacter();
+
+ /**
+ * Determine if the next character on the sream is a {@link XmlCharacters#isValidNcName(int) valid XML NCName character}.
+ * This method does <i>not</i> advance the stream.
+ *
+ * @return true if there is a {@link #next() next} character and it is a valid XML NCName character, or false otherwise
+ */
+ boolean isNextValidXmlNcNameCharacter();
+
+ /**
* Determine if the next character on the sream is the supplied value. This method does <i>not</i> advance the stream.
*
* @param c the character value to compare to the next character on the stream
@@ -1882,6 +1898,26 @@
int nextIndex = lastIndex + 1;
return nextIndex <= maxIndex && XmlCharacters.isValid(content[nextIndex]);
}
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.jboss.dna.common.text.TokenStream.CharacterStream#isNextValidXmlNameCharacter()
+ */
+ public boolean isNextValidXmlNameCharacter() {
+ int nextIndex = lastIndex + 1;
+ return nextIndex <= maxIndex && XmlCharacters.isValidName(content[nextIndex]);
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.jboss.dna.common.text.TokenStream.CharacterStream#isNextValidXmlNcNameCharacter()
+ */
+ public boolean isNextValidXmlNcNameCharacter() {
+ int nextIndex = lastIndex + 1;
+ return nextIndex <= maxIndex && XmlCharacters.isValidNcName(content[nextIndex]);
+ }
}
/**
Added: trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/xpath/XPath.java
===================================================================
--- trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/xpath/XPath.java (rev 0)
+++ trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/xpath/XPath.java 2009-10-03 04:07:41 UTC (rev 1285)
@@ -0,0 +1,1132 @@
+/*
+ * JBoss DNA (http://www.jboss.org/dna)
+ * 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.
+ * See the AUTHORS.txt file in the distribution for a full listing of
+ * individual contributors.
+ *
+ * JBoss DNA is free software. Unless otherwise indicated, all code in JBoss DNA
+ * is licensed to you 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.
+ *
+ * JBoss DNA 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 software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.dna.jcr.xpath;
+
+import java.util.List;
+import org.jboss.dna.common.util.CheckArg;
+import org.jboss.dna.common.util.ObjectUtil;
+import org.jboss.dna.graph.query.model.Operator;
+
+/**
+ *
+ */
+public class XPath {
+
+ public static enum NodeComparisonOperator {
+ IS,
+ PRECEDES,
+ FOLLOWS;
+ }
+
+ public static interface Component {
+ }
+
+ public static abstract class UnaryComponent implements Component {
+ protected final Component wrapped;
+
+ public UnaryComponent( Component wrapped ) {
+ this.wrapped = wrapped;
+ }
+ }
+
+ public static class Negation extends UnaryComponent {
+ public Negation( Component wrapped ) {
+ super(wrapped);
+ }
+
+ public Component getNegated() {
+ return wrapped;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see java.lang.Object#toString()
+ */
+ @Override
+ public String toString() {
+ return "-" + wrapped;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see java.lang.Object#equals(java.lang.Object)
+ */
+ @Override
+ public boolean equals( Object obj ) {
+ if (obj == this) return true;
+ if (obj instanceof Negation) {
+ Negation that = (Negation)obj;
+ return this.wrapped.equals(that.wrapped);
+ }
+ return false;
+ }
+ }
+
+ public static abstract class BinaryComponent implements Component {
+ private final Component left;
+ private final Component right;
+
+ public BinaryComponent( Component left,
+ Component right ) {
+ this.left = left;
+ this.right = right;
+ }
+
+ /**
+ * @return left
+ */
+ public Component getLeft() {
+ return left;
+ }
+
+ /**
+ * @return right
+ */
+ public Component getRight() {
+ return right;
+ }
+ }
+
+ public static class Comparison extends BinaryComponent {
+ private final Operator operator;
+
+ public Comparison( Component left,
+ Operator operator,
+ Component right ) {
+ super(left, right);
+ this.operator = operator;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see java.lang.Object#toString()
+ */
+ @Override
+ public String toString() {
+ return getLeft() + " " + operator + " " + getRight();
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see java.lang.Object#equals(java.lang.Object)
+ */
+ @Override
+ public boolean equals( Object obj ) {
+ if (obj == this) return true;
+ if (obj instanceof Comparison) {
+ Comparison that = (Comparison)obj;
+ if (this.operator != that.operator) return false;
+ return this.getLeft().equals(that.getLeft()) && this.getRight().equals(that.getRight());
+ }
+ return false;
+ }
+ }
+
+ public static class NodeComparison extends BinaryComponent {
+ private final NodeComparisonOperator operator;
+
+ public NodeComparison( Component left,
+ NodeComparisonOperator operator,
+ Component right ) {
+ super(left, right);
+ this.operator = operator;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see java.lang.Object#toString()
+ */
+ @Override
+ public String toString() {
+ return getLeft() + " " + operator + " " + getRight();
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see java.lang.Object#equals(java.lang.Object)
+ */
+ @Override
+ public boolean equals( Object obj ) {
+ if (obj == this) return true;
+ if (obj instanceof NodeComparison) {
+ NodeComparison that = (NodeComparison)obj;
+ if (this.operator != that.operator) return false;
+ return this.getLeft().equals(that.getLeft()) && this.getRight().equals(that.getRight());
+ }
+ return false;
+ }
+ }
+
+ public static class Add extends BinaryComponent {
+ public Add( Component left,
+ Component right ) {
+ super(left, right);
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see java.lang.Object#toString()
+ */
+ @Override
+ public String toString() {
+ return getLeft() + " + " + getRight();
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see java.lang.Object#equals(java.lang.Object)
+ */
+ @Override
+ public boolean equals( Object obj ) {
+ if (obj == this) return true;
+ if (obj instanceof Add) {
+ Add that = (Add)obj;
+ return this.getLeft().equals(that.getLeft()) && this.getRight().equals(that.getRight());
+ }
+ return false;
+ }
+ }
+
+ public static class Subtract extends BinaryComponent {
+ public Subtract( Component left,
+ Component right ) {
+ super(left, right);
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see java.lang.Object#toString()
+ */
+ @Override
+ public String toString() {
+ return getLeft() + " - " + getRight();
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see java.lang.Object#equals(java.lang.Object)
+ */
+ @Override
+ public boolean equals( Object obj ) {
+ if (obj == this) return true;
+ if (obj instanceof Subtract) {
+ Subtract that = (Subtract)obj;
+ return this.getLeft().equals(that.getLeft()) && this.getRight().equals(that.getRight());
+ }
+ return false;
+ }
+ }
+
+ public static class And extends BinaryComponent {
+ public And( Component left,
+ Component right ) {
+ super(left, right);
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see java.lang.Object#toString()
+ */
+ @Override
+ public String toString() {
+ return getLeft() + " and " + getRight();
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see java.lang.Object#equals(java.lang.Object)
+ */
+ @Override
+ public boolean equals( Object obj ) {
+ if (obj == this) return true;
+ if (obj instanceof And) {
+ And that = (And)obj;
+ return this.getLeft().equals(that.getLeft()) && this.getRight().equals(that.getRight());
+ }
+ return false;
+ }
+ }
+
+ public static class Union extends BinaryComponent {
+ public Union( Component left,
+ Component right ) {
+ super(left, right);
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see java.lang.Object#toString()
+ */
+ @Override
+ public String toString() {
+ return getLeft() + " union " + getRight();
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see java.lang.Object#equals(java.lang.Object)
+ */
+ @Override
+ public boolean equals( Object obj ) {
+ if (obj == this) return true;
+ if (obj instanceof Union) {
+ Union that = (Union)obj;
+ return this.getLeft().equals(that.getLeft()) && this.getRight().equals(that.getRight());
+ }
+ return false;
+ }
+ }
+
+ public static class Or extends BinaryComponent {
+ public Or( Component left,
+ Component right ) {
+ super(left, right);
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see java.lang.Object#toString()
+ */
+ @Override
+ public String toString() {
+ return getLeft() + " or " + getRight();
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see java.lang.Object#equals(java.lang.Object)
+ */
+ @Override
+ public boolean equals( Object obj ) {
+ if (obj == this) return true;
+ if (obj instanceof Or) {
+ Or that = (Or)obj;
+ return this.getLeft().equals(that.getLeft()) && this.getRight().equals(that.getRight());
+ }
+ return false;
+ }
+ }
+
+ public static class ContextItem implements Component {
+ /**
+ * {@inheritDoc}
+ *
+ * @see java.lang.Object#equals(java.lang.Object)
+ */
+ @Override
+ public boolean equals( Object obj ) {
+ return obj == this || obj instanceof ContextItem;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see java.lang.Object#toString()
+ */
+ @Override
+ public String toString() {
+ return ".";
+ }
+ }
+
+ public static class Literal implements Component {
+ private final String value;
+
+ public Literal( String value ) {
+ this.value = value;
+ }
+
+ /**
+ * @return value
+ */
+ public String getValue() {
+ return value;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see java.lang.Object#equals(java.lang.Object)
+ */
+ @Override
+ public boolean equals( Object obj ) {
+ if (obj == this) return true;
+ if (obj instanceof Literal) {
+ return this.value.equals(((Literal)obj).value);
+ }
+ return false;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see java.lang.Object#toString()
+ */
+ @Override
+ public String toString() {
+ return value;
+ }
+ }
+
+ public static class FunctionCall implements Component {
+ private final NameTest name;
+ private final List<Component> arguments;
+
+ public FunctionCall( NameTest name,
+ List<Component> arguments ) {
+ assert name != null;
+ assert arguments != null;
+ this.name = name;
+ this.arguments = arguments;
+ }
+
+ /**
+ * @return name
+ */
+ public NameTest getName() {
+ return name;
+ }
+
+ /**
+ * @return arguments
+ */
+ public List<Component> getParameters() {
+ return arguments;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see java.lang.Object#equals(java.lang.Object)
+ */
+ @Override
+ public boolean equals( Object obj ) {
+ if (obj == this) return true;
+ if (obj instanceof FunctionCall) {
+ FunctionCall that = (FunctionCall)obj;
+ return this.name.equals(that.name) && this.arguments.equals(that.arguments);
+ }
+ return false;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see java.lang.Object#toString()
+ */
+ @Override
+ public String toString() {
+ return name + "(" + asString(arguments, ",") + ")";
+ }
+ }
+
+ protected static String asString( Iterable<?> components,
+ String delimiter ) {
+ StringBuilder sb = new StringBuilder();
+ for (Object component : components) {
+ if (sb.length() != 0) sb.append(delimiter);
+ sb.append(component);
+ }
+ return sb.toString();
+ }
+
+ public static class PathExpression implements Component {
+ private final List<StepExpression> steps;
+ private final boolean relative;
+
+ public PathExpression( boolean relative,
+ List<StepExpression> steps ) {
+ this.steps = steps;
+ this.relative = relative;
+ }
+
+ /**
+ * @return relative
+ */
+ public boolean isRelative() {
+ return relative;
+ }
+
+ /**
+ * @return steps
+ */
+ public List<StepExpression> getSteps() {
+ return steps;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see java.lang.Object#equals(java.lang.Object)
+ */
+ @Override
+ public boolean equals( Object obj ) {
+ if (obj == this) return true;
+ if (obj instanceof PathExpression) {
+ PathExpression that = (PathExpression)obj;
+ return this.relative == that.relative && this.steps.equals(that.steps);
+ }
+ return false;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see java.lang.Object#toString()
+ */
+ @Override
+ public String toString() {
+ return (relative ? "" : "/") + asString(steps, "/");
+ }
+ }
+
+ public static interface StepExpression extends Component {
+ }
+
+ public static class FilterStep implements StepExpression {
+ private final Component primaryExpression;
+ private final List<Component> predicates;
+
+ public FilterStep( Component primaryExpression,
+ List<Component> predicates ) {
+ assert primaryExpression != null;
+ assert predicates != null;
+ this.primaryExpression = primaryExpression;
+ this.predicates = predicates;
+ }
+
+ /**
+ * @return nodeTest
+ */
+ public Component getPrimaryExpression() {
+ return primaryExpression;
+ }
+
+ /**
+ * @return predicates
+ */
+ public List<Component> getPredicates() {
+ return predicates;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see java.lang.Object#equals(java.lang.Object)
+ */
+ @Override
+ public boolean equals( Object obj ) {
+ if (obj == this) return true;
+ if (obj instanceof FilterStep) {
+ FilterStep that = (FilterStep)obj;
+ return this.primaryExpression.equals(that.primaryExpression) && this.predicates.equals(that.predicates);
+ }
+ return false;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see java.lang.Object#toString()
+ */
+ @Override
+ public String toString() {
+ return primaryExpression + (predicates.isEmpty() ? "" : predicates.toString());
+ }
+ }
+
+ public static class DescendantOrSelf implements StepExpression {
+ /**
+ * {@inheritDoc}
+ *
+ * @see java.lang.Object#equals(java.lang.Object)
+ */
+ @Override
+ public boolean equals( Object obj ) {
+ return obj == this || obj instanceof DescendantOrSelf;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see java.lang.Object#toString()
+ */
+ @Override
+ public String toString() {
+ return "descendant-or-self::node()";
+ }
+ }
+
+ public static class AxisStep implements StepExpression {
+ private final NodeTest nodeTest;
+ private final List<Component> predicates;
+
+ public AxisStep( NodeTest nodeTest,
+ List<Component> predicates ) {
+ assert nodeTest != null;
+ assert predicates != null;
+ this.nodeTest = nodeTest;
+ this.predicates = predicates;
+ }
+
+ /**
+ * @return nodeTest
+ */
+ public NodeTest getNodeTest() {
+ return nodeTest;
+ }
+
+ /**
+ * @return predicates
+ */
+ public List<Component> getPredicates() {
+ return predicates;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see java.lang.Object#equals(java.lang.Object)
+ */
+ @Override
+ public boolean equals( Object obj ) {
+ if (obj == this) return true;
+ if (obj instanceof AxisStep) {
+ AxisStep that = (AxisStep)obj;
+ return this.nodeTest.equals(that.nodeTest) && this.predicates.equals(that.predicates);
+ }
+ return false;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see java.lang.Object#toString()
+ */
+ @Override
+ public String toString() {
+ return nodeTest + (predicates.isEmpty() ? "" : predicates.toString());
+ }
+ }
+
+ public static class ParenthesizedExpression implements Component {
+ private final Component wrapped;
+
+ public ParenthesizedExpression() {
+ this.wrapped = null;
+ }
+
+ public ParenthesizedExpression( Component wrapped ) {
+ this.wrapped = wrapped; // may be null
+ }
+
+ /**
+ * @return wrapped
+ */
+ public Component getWrapped() {
+ return wrapped;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see java.lang.Object#equals(java.lang.Object)
+ */
+ @Override
+ public boolean equals( Object obj ) {
+ if (obj == this) return true;
+ if (obj instanceof ParenthesizedExpression) {
+ ParenthesizedExpression that = (ParenthesizedExpression)obj;
+ return this.wrapped.equals(that.wrapped);
+ }
+ return false;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see java.lang.Object#toString()
+ */
+ @Override
+ public String toString() {
+ return "(" + wrapped + ")";
+ }
+ }
+
+ public static interface NodeTest extends Component {
+ }
+
+ public static interface KindTest extends NodeTest {
+ }
+
+ public static class NameTest implements NodeTest {
+ private final String prefixTest;
+ private final String localTest;
+
+ public NameTest( String prefixTest,
+ String localTest ) {
+ this.prefixTest = prefixTest;
+ this.localTest = localTest;
+ }
+
+ /**
+ * @return prefixTest
+ */
+ public String getPrefixTest() {
+ return prefixTest;
+ }
+
+ /**
+ * @return localTest
+ */
+ public String getLocalTest() {
+ return localTest;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see java.lang.Object#equals(java.lang.Object)
+ */
+ @Override
+ public boolean equals( Object obj ) {
+ if (obj == this) return true;
+ if (obj instanceof NameTest) {
+ NameTest that = (NameTest)obj;
+ return ObjectUtil.isEqualWithNulls(this.prefixTest, that.prefixTest)
+ && ObjectUtil.isEqualWithNulls(this.localTest, that.localTest);
+ }
+ return false;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see java.lang.Object#toString()
+ */
+ @Override
+ public String toString() {
+ String local = localTest != null ? localTest : "*";
+ return prefixTest == null ? local : (prefixTest + ":" + local);
+ }
+ }
+
+ public static class AttributeNameTest implements NodeTest {
+ private final NodeTest nodeTest;
+
+ public AttributeNameTest( NodeTest nodeTest ) {
+ this.nodeTest = nodeTest;
+ }
+
+ /**
+ * @return nodeTest
+ */
+ public NodeTest getNodeTest() {
+ return nodeTest;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see XPath.NameTest#toString()
+ */
+ @Override
+ public String toString() {
+ return "@" + nodeTest;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see java.lang.Object#equals(java.lang.Object)
+ */
+ @Override
+ public boolean equals( Object obj ) {
+ if (obj == this) return true;
+ if (obj instanceof AttributeNameTest) {
+ AttributeNameTest that = (AttributeNameTest)obj;
+ return this.nodeTest.equals(that.nodeTest);
+ }
+ return false;
+ }
+
+ }
+
+ public static class AnyKindTest implements KindTest {
+ /**
+ * {@inheritDoc}
+ *
+ * @see java.lang.Object#equals(java.lang.Object)
+ */
+ @Override
+ public boolean equals( Object obj ) {
+ return obj == this || obj instanceof AnyKindTest;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see java.lang.Object#toString()
+ */
+ @Override
+ public String toString() {
+ return "node()";
+ }
+ }
+
+ public static class TextTest implements KindTest {
+ /**
+ * {@inheritDoc}
+ *
+ * @see java.lang.Object#equals(java.lang.Object)
+ */
+ @Override
+ public boolean equals( Object obj ) {
+ return obj == this || obj instanceof TextTest;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see java.lang.Object#toString()
+ */
+ @Override
+ public String toString() {
+ return "text()";
+ }
+ }
+
+ public static class CommentTest implements KindTest {
+ /**
+ * {@inheritDoc}
+ *
+ * @see java.lang.Object#equals(java.lang.Object)
+ */
+ @Override
+ public boolean equals( Object obj ) {
+ return obj == this || obj instanceof CommentTest;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see java.lang.Object#toString()
+ */
+ @Override
+ public String toString() {
+ return "comment()";
+ }
+ }
+
+ public static class ProcessingInstructionTest implements KindTest {
+ private final String nameOrStringLiteral;
+
+ public ProcessingInstructionTest( String nameOrStringLiteral ) {
+ this.nameOrStringLiteral = nameOrStringLiteral;
+ }
+
+ /**
+ * @return nameOrStringLiteral
+ */
+ public String getNameOrStringLiteral() {
+ return nameOrStringLiteral;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see java.lang.Object#equals(java.lang.Object)
+ */
+ @Override
+ public boolean equals( Object obj ) {
+ if (obj == this) return true;
+ if (obj instanceof ProcessingInstructionTest) {
+ ProcessingInstructionTest that = (ProcessingInstructionTest)obj;
+ return this.nameOrStringLiteral.equals(that.nameOrStringLiteral);
+ }
+ return false;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see java.lang.Object#toString()
+ */
+ @Override
+ public String toString() {
+ return "processing-instruction(" + nameOrStringLiteral + ")";
+ }
+ }
+
+ public static class DocumentTest implements KindTest {
+ private KindTest elementOrSchemaElementTest;
+
+ public DocumentTest( ElementTest elementTest ) {
+ CheckArg.isNotNull(elementTest, "elementTest");
+ this.elementOrSchemaElementTest = elementTest;
+ }
+
+ public DocumentTest( SchemaElementTest schemaElementTest ) {
+ CheckArg.isNotNull(schemaElementTest, "schemaElementTest");
+ this.elementOrSchemaElementTest = schemaElementTest;
+ }
+
+ /**
+ * @return elementOrSchemaElementTest
+ */
+ public ElementTest getElementTest() {
+ return elementOrSchemaElementTest instanceof ElementTest ? (ElementTest)elementOrSchemaElementTest : null;
+ }
+
+ /**
+ * @return elementOrSchemaElementTest
+ */
+ public SchemaElementTest getSchemaElementTest() {
+ return elementOrSchemaElementTest instanceof SchemaElementTest ? (SchemaElementTest)elementOrSchemaElementTest : null;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see java.lang.Object#equals(java.lang.Object)
+ */
+ @Override
+ public boolean equals( Object obj ) {
+ if (obj == this) return true;
+ if (obj instanceof DocumentTest) {
+ DocumentTest that = (DocumentTest)obj;
+ return this.elementOrSchemaElementTest.equals(that.elementOrSchemaElementTest);
+ }
+ return false;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see java.lang.Object#toString()
+ */
+ @Override
+ public String toString() {
+ return "document-node(" + elementOrSchemaElementTest + ")";
+ }
+ }
+
+ public static class AttributeTest implements KindTest {
+ private final NameTest attributeNameOrWildcard;
+ private final NameTest typeName;
+
+ public AttributeTest( NameTest attributeNameOrWildcard,
+ NameTest typeName ) {
+ this.attributeNameOrWildcard = attributeNameOrWildcard;
+ this.typeName = typeName;
+ }
+
+ /**
+ *@return the attribute name, which may be a wilcard
+ */
+ public NameTest getAttributeName() {
+ return attributeNameOrWildcard;
+ }
+
+ /**
+ * @return typeName
+ */
+ public NameTest getTypeName() {
+ return typeName;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see java.lang.Object#equals(java.lang.Object)
+ */
+ @Override
+ public boolean equals( Object obj ) {
+ if (obj == this) return true;
+ if (obj instanceof AttributeTest) {
+ AttributeTest that = (AttributeTest)obj;
+ return ObjectUtil.isEqualWithNulls(this.typeName, that.typeName)
+ && ObjectUtil.isEqualWithNulls(this.attributeNameOrWildcard, that.attributeNameOrWildcard);
+ }
+ return false;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see java.lang.Object#toString()
+ */
+ @Override
+ public String toString() {
+ return "attribute(" + attributeNameOrWildcard + (typeName != null ? "," + typeName : "") + ")";
+ }
+ }
+
+ public static class ElementTest implements KindTest {
+ private final NameTest elementNameOrWildcard;
+ private final NameTest typeName;
+
+ public ElementTest( NameTest elementNameOrWildcard,
+ NameTest typeName ) {
+ this.elementNameOrWildcard = elementNameOrWildcard;
+ this.typeName = typeName;
+ }
+
+ /**
+ *@return the element name, which may be a wilcard
+ */
+ public NameTest getElementName() {
+ return elementNameOrWildcard;
+ }
+
+ /**
+ * @return typeName
+ */
+ public NameTest getTypeName() {
+ return typeName;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see java.lang.Object#equals(java.lang.Object)
+ */
+ @Override
+ public boolean equals( Object obj ) {
+ if (obj == this) return true;
+ if (obj instanceof ElementTest) {
+ ElementTest that = (ElementTest)obj;
+ return ObjectUtil.isEqualWithNulls(this.typeName, that.typeName)
+ && ObjectUtil.isEqualWithNulls(this.elementNameOrWildcard, that.elementNameOrWildcard);
+ }
+ return false;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see java.lang.Object#toString()
+ */
+ @Override
+ public String toString() {
+ return "element(" + elementNameOrWildcard + (typeName != null ? "," + typeName : "") + ")";
+ }
+ }
+
+ public static class SchemaElementTest implements KindTest {
+ private final NameTest elementDeclarationName;
+
+ public SchemaElementTest( NameTest elementDeclarationName ) {
+ this.elementDeclarationName = elementDeclarationName;
+ }
+
+ /**
+ *@return the element declaration name, which will be a qualified name
+ */
+ public NameTest getElementDeclarationName() {
+ return elementDeclarationName;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see java.lang.Object#equals(java.lang.Object)
+ */
+ @Override
+ public boolean equals( Object obj ) {
+ if (obj == this) return true;
+ if (obj instanceof SchemaElementTest) {
+ SchemaElementTest that = (SchemaElementTest)obj;
+ return this.elementDeclarationName.equals(that.elementDeclarationName);
+ }
+ return false;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see java.lang.Object#toString()
+ */
+ @Override
+ public String toString() {
+ return "schema-element(" + elementDeclarationName + ")";
+ }
+ }
+
+ public static class SchemaAttributeTest implements KindTest {
+ private final NameTest attributeDeclarationName;
+
+ public SchemaAttributeTest( NameTest attributeDeclarationName ) {
+ this.attributeDeclarationName = attributeDeclarationName;
+ }
+
+ /**
+ *@return the attribute declaration name, which will be a qualified name
+ */
+ public NameTest getAttributeDeclarationName() {
+ return attributeDeclarationName;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see java.lang.Object#equals(java.lang.Object)
+ */
+ @Override
+ public boolean equals( Object obj ) {
+ if (obj == this) return true;
+ if (obj instanceof SchemaAttributeTest) {
+ SchemaAttributeTest that = (SchemaAttributeTest)obj;
+ return this.attributeDeclarationName.equals(that.attributeDeclarationName);
+ }
+ return false;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see java.lang.Object#toString()
+ */
+ @Override
+ public String toString() {
+ return "schema-attribute(" + attributeDeclarationName + ")";
+ }
+ }
+}
Property changes on: trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/xpath/XPath.java
___________________________________________________________________
Name: svn:keywords
+ Id Revision
Name: svn:eol-style
+ LF
Added: trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/xpath/XPathParser.java
===================================================================
--- trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/xpath/XPathParser.java (rev 0)
+++ trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/xpath/XPathParser.java 2009-10-03 04:07:41 UTC (rev 1285)
@@ -0,0 +1,812 @@
+/*
+ * JBoss DNA (http://www.jboss.org/dna)
+ * 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.
+ * See the AUTHORS.txt file in the distribution for a full listing of
+ * individual contributors.
+ *
+ * JBoss DNA is free software. Unless otherwise indicated, all code in JBoss DNA
+ * is licensed to you 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.
+ *
+ * JBoss DNA 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 software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.dna.jcr.xpath;
+
+import static org.jboss.dna.common.text.TokenStream.ANY_VALUE;
+import java.util.ArrayList;
+import java.util.List;
+import org.jboss.dna.common.CommonI18n;
+import org.jboss.dna.common.text.ParsingException;
+import org.jboss.dna.common.text.Position;
+import org.jboss.dna.common.text.TokenStream;
+import org.jboss.dna.common.text.TokenStream.CharacterStream;
+import org.jboss.dna.common.text.TokenStream.Tokenizer;
+import org.jboss.dna.common.text.TokenStream.Tokens;
+import org.jboss.dna.common.xml.XmlCharacters;
+import org.jboss.dna.graph.ExecutionContext;
+import org.jboss.dna.graph.GraphI18n;
+import org.jboss.dna.graph.property.ValueFactory;
+import org.jboss.dna.graph.property.ValueFormatException;
+import org.jboss.dna.graph.query.model.Operator;
+import org.jboss.dna.graph.query.model.QueryCommand;
+import org.jboss.dna.graph.query.parse.QueryParser;
+import org.jboss.dna.jcr.xpath.XPath.Add;
+import org.jboss.dna.jcr.xpath.XPath.And;
+import org.jboss.dna.jcr.xpath.XPath.AnyKindTest;
+import org.jboss.dna.jcr.xpath.XPath.AttributeNameTest;
+import org.jboss.dna.jcr.xpath.XPath.AttributeTest;
+import org.jboss.dna.jcr.xpath.XPath.AxisStep;
+import org.jboss.dna.jcr.xpath.XPath.CommentTest;
+import org.jboss.dna.jcr.xpath.XPath.Comparison;
+import org.jboss.dna.jcr.xpath.XPath.Component;
+import org.jboss.dna.jcr.xpath.XPath.ContextItem;
+import org.jboss.dna.jcr.xpath.XPath.DescendantOrSelf;
+import org.jboss.dna.jcr.xpath.XPath.DocumentTest;
+import org.jboss.dna.jcr.xpath.XPath.ElementTest;
+import org.jboss.dna.jcr.xpath.XPath.FilterStep;
+import org.jboss.dna.jcr.xpath.XPath.FunctionCall;
+import org.jboss.dna.jcr.xpath.XPath.KindTest;
+import org.jboss.dna.jcr.xpath.XPath.Literal;
+import org.jboss.dna.jcr.xpath.XPath.NameTest;
+import org.jboss.dna.jcr.xpath.XPath.Negation;
+import org.jboss.dna.jcr.xpath.XPath.NodeComparison;
+import org.jboss.dna.jcr.xpath.XPath.NodeComparisonOperator;
+import org.jboss.dna.jcr.xpath.XPath.NodeTest;
+import org.jboss.dna.jcr.xpath.XPath.Or;
+import org.jboss.dna.jcr.xpath.XPath.ParenthesizedExpression;
+import org.jboss.dna.jcr.xpath.XPath.PathExpression;
+import org.jboss.dna.jcr.xpath.XPath.ProcessingInstructionTest;
+import org.jboss.dna.jcr.xpath.XPath.SchemaAttributeTest;
+import org.jboss.dna.jcr.xpath.XPath.SchemaElementTest;
+import org.jboss.dna.jcr.xpath.XPath.StepExpression;
+import org.jboss.dna.jcr.xpath.XPath.Subtract;
+import org.jboss.dna.jcr.xpath.XPath.TextTest;
+import org.jboss.dna.jcr.xpath.XPath.Union;
+
+/**
+ *
+ */
+public class XPathParser implements QueryParser {
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.jboss.dna.graph.query.parse.QueryParser#parseQuery(java.lang.String, org.jboss.dna.graph.ExecutionContext)
+ */
+ public QueryCommand parseQuery( String query,
+ ExecutionContext context ) {
+ Tokenizer tokenizer = new XPathTokenizer(false); // skip comments
+ TokenStream tokens = new TokenStream(query, tokenizer, true).start(); // case sensitive!!
+ Component result = new Parser(context).parseXPath(tokens);
+ System.out.println(query);
+ System.out.println(" --> " + result);
+ return null;
+ }
+
+ protected static class Parser {
+ private final ExecutionContext context;
+
+ protected Parser( ExecutionContext context ) {
+ this.context = context;
+ }
+
+ protected Component parseXPath( TokenStream tokens ) {
+ return parseExpr(tokens);
+ }
+
+ protected Component parseExpr( TokenStream tokens ) {
+ Component result = parseExprSingle(tokens);
+ if (tokens.matches(',')) {
+ throw new ParsingException(tokens.nextPosition(), "Multiple XPath expressions are not supported");
+ }
+ return result;
+ }
+
+ protected Component parseExprSingle( TokenStream tokens ) {
+ if (tokens.matches("for", "$", ANY_VALUE, "IN")) {
+ throw new ParsingException(tokens.nextPosition(), "XPath 'for' expressions are not supported");
+ }
+ if (tokens.matches("some", "$", ANY_VALUE, "IN")) {
+ throw new ParsingException(tokens.nextPosition(), "XPath 'some' expressions are not supported");
+ }
+ if (tokens.matches("every", "$", ANY_VALUE, "IN")) {
+ throw new ParsingException(tokens.nextPosition(), "XPath 'every' expressions are not supported");
+ }
+ if (tokens.matches("if", "(", ANY_VALUE, "IN")) {
+ throw new ParsingException(tokens.nextPosition(), "XPath if-then-else expressions are not supported");
+ }
+ return parseOrExpr(tokens);
+ }
+
+ protected Component parseOrExpr( TokenStream tokens ) {
+ Component result = parseAndExpr(tokens);
+ while (tokens.canConsume("or")) {
+ result = new Or(result, parseInstanceofExpr(tokens));
+ }
+ return result;
+ }
+
+ protected Component parseAndExpr( TokenStream tokens ) {
+ Component result = parseInstanceofExpr(tokens);
+ while (tokens.canConsume("and")) {
+ result = new And(result, parseInstanceofExpr(tokens));
+ }
+ return result;
+ }
+
+ protected Component parseInstanceofExpr( TokenStream tokens ) {
+ Component result = parseTreatExpr(tokens);
+ if (tokens.matches("instance", "of")) {
+ throw new ParsingException(tokens.nextPosition(), "XPath 'instance of' expressions are not supported");
+ }
+ return result;
+ }
+
+ protected Component parseTreatExpr( TokenStream tokens ) {
+ Component result = parseCastableExpr(tokens);
+ if (tokens.matches("treat", "as")) {
+ throw new ParsingException(tokens.nextPosition(), "XPath 'treat as' expressions are not supported");
+ }
+ return result;
+ }
+
+ protected Component parseCastableExpr( TokenStream tokens ) {
+ Component result = parseCastExpr(tokens);
+ if (tokens.matches("castable", "as")) {
+ throw new ParsingException(tokens.nextPosition(), "XPath 'castable as' expressions are not supported");
+ }
+ return result;
+ }
+
+ protected Component parseCastExpr( TokenStream tokens ) {
+ Component result = parseComparisonExpr(tokens);
+ if (tokens.matches("cast", "as")) {
+ throw new ParsingException(tokens.nextPosition(), "XPath 'cast as' expressions are not supported");
+ }
+ return result;
+ }
+
+ protected Component parseComparisonExpr( TokenStream tokens ) {
+ Component result = parseRangeExpr(tokens);
+ // General comparison is optional ...
+ Operator operator = parseGeneralComp(tokens);
+ if (operator == null) parseValueComp(tokens);
+ if (operator != null) {
+ return new Comparison(result, operator, parseRangeExpr(tokens));
+ }
+ NodeComparisonOperator nodeComp = parseNodeComp(tokens);
+ if (nodeComp != null) {
+ return new NodeComparison(result, nodeComp, parseRangeExpr(tokens));
+ }
+ return result;
+ }
+
+ protected Component parseValueComp( TokenStream tokens ) {
+ if (tokens.matchesAnyOf("eq", "ne", "lt", "le", "gt")) {
+ throw new ParsingException(tokens.nextPosition(),
+ "XPath value comparisons using 'eq', 'ne', 'lt', 'le', or 'gt' are not supported");
+ }
+ return null;
+ }
+
+ protected NodeComparisonOperator parseNodeComp( TokenStream tokens ) {
+ if (tokens.matches("is") || tokens.matches("<", "<") || tokens.matches(">", ">")) {
+ throw new ParsingException(tokens.nextPosition(), "XPath 'is', '<<' and '>>' expressions are not supported");
+ }
+ return null;
+ }
+
+ protected Component parseRangeExpr( TokenStream tokens ) {
+ Component result = parseAdditiveExpr(tokens);
+ if (tokens.matches("to")) {
+ throw new ParsingException(tokens.nextPosition(), "XPath range expressions with 'to' are not supported");
+ }
+ return result;
+ }
+
+ protected Component parseAdditiveExpr( TokenStream tokens ) {
+ Component result = parseMultiplicativeExpr(tokens);
+ while (true) {
+ if (tokens.canConsume("+")) {
+ result = new Add(result, parseMultiplicativeExpr(tokens));
+ } else if (tokens.canConsume("-")) {
+ result = new Subtract(result, parseMultiplicativeExpr(tokens));
+ } else {
+ break; // no more additions
+ }
+ }
+ return result;
+ }
+
+ protected Component parseMultiplicativeExpr( TokenStream tokens ) {
+ Component result = parseUnaryExpr(tokens);
+ if (tokens.matchesAnyOf("+", "div", "idiv", "mod")) {
+ throw new ParsingException(tokens.nextPosition(),
+ "XPath multiplicative expressions using '+', 'div', 'idiv', or 'mod' are not supported");
+ }
+ return result;
+ }
+
+ protected Component parseUnaryExpr( TokenStream tokens ) {
+ boolean negative = false;
+ // Technically more than one +/- are allowed by the spec
+ while (tokens.matchesAnyOf("+", "-")) {
+ if (tokens.canConsume("-")) negative = true;
+ tokens.canConsume("+");
+ }
+ Component result = parseUnionExpr(tokens);
+ return negative ? new Negation(result) : result;
+ }
+
+ protected Component parseUnionExpr( TokenStream tokens ) {
+ Component result = parseIntersectExceptExpr(tokens);
+ while (true) {
+ if (tokens.canConsumeAnyOf("union", "|")) {
+ result = new Union(result, parseIntersectExceptExpr(tokens));
+ } else {
+ break; // no more
+ }
+ }
+ return result;
+ }
+
+ protected Component parseIntersectExceptExpr( TokenStream tokens ) {
+ Component result = parseValueExpr(tokens);
+ if (tokens.matchesAnyOf("intersect", "except")) {
+ throw new ParsingException(tokens.nextPosition(),
+ "XPath multiplicative expressions using '+', 'div', 'idiv', or 'mod' are not supported");
+ }
+ return result;
+ }
+
+ protected Component parseValueExpr( TokenStream tokens ) {
+ return parsePathExpr(tokens);
+ }
+
+ protected PathExpression parsePathExpr( TokenStream tokens ) {
+ boolean relative = true;
+ boolean prependDependentOrSelf = false;
+ if (tokens.canConsume('/')) {
+ if (tokens.canConsume('/')) {
+ if (!tokens.hasNext()) {
+ // See http://www.w3.org/XML/2007/qt-errata/xpath20-errata.html#E3
+ throw new ParsingException(tokens.previousPosition(), "'//' is not a valid XPath expression");
+ }
+ prependDependentOrSelf = true;
+ }
+ relative = false;
+ }
+ PathExpression result = new PathExpression(relative, parseRelativePathExpr(tokens).getSteps());
+ if (prependDependentOrSelf) {
+ result.getSteps().add(0, new DescendantOrSelf());
+ }
+ return result;
+ }
+
+ protected PathExpression parseRelativePathExpr( TokenStream tokens ) {
+ List<StepExpression> steps = new ArrayList<StepExpression>();
+ steps.add(parseStepExpr(tokens));
+ while (tokens.canConsume('/')) {
+ if (tokens.canConsume('/')) {
+ steps.add(new DescendantOrSelf());
+ }
+ if (tokens.hasNext()) {
+ steps.add(parseStepExpr(tokens));
+ }
+ }
+ return new PathExpression(true, steps);
+ }
+
+ protected StepExpression parseStepExpr( TokenStream tokens ) {
+ if (tokens.matches('(') || tokens.matches('.') || tokens.matches(XPathTokenizer.QUOTED_STRING)
+ || tokens.matches(ANY_VALUE, "(") || tokens.matches(ANY_VALUE, ":", ANY_VALUE, "(")) {
+ // We know its a filter expression (though literals don't fit this pattern) ...
+ return parseFilterExpr(tokens);
+ }
+ AxisStep result = parseAxisStep(tokens);
+ if (result != null) return result;
+ // It must be the remaining kind of filter expression ...
+ return parseFilterExpr(tokens);
+ }
+
+ protected AxisStep parseAxisStep( TokenStream tokens ) {
+ NodeTest nodeTest = null;
+ if (tokens.canConsume('@')) {
+ // Abbreviated forward step with an attribute...
+ nodeTest = new AttributeNameTest(parseNodeTest(tokens));
+ } else if (tokens.matches('*')) {
+ // Abbreviated forward step with an wildcard element ...
+ nodeTest = parseNodeTest(tokens);
+
+ } else if (tokens.matches("child", ":", ":") || tokens.matches("attribute", ":", ":")
+ || tokens.matches("self", ":", ":") || tokens.matches("descendant", ":", ":")
+ || tokens.matches("descendant-or-self", ":", ":") || tokens.matches("following-sibling", ":", ":")
+ || tokens.matches("following", ":", ":") || tokens.matches("namespace", ":", ":")) {
+ // No non-abbreviated forward steps allowed
+ throw new ParsingException(
+ tokens.nextPosition(),
+ "XPath non-abbreviated forward steps (e.g., 'child::', 'attribute::', 'self::', 'descendant::', 'descendant-or-self::', 'following-sibling::', 'following::', or 'namespace::') are not supported");
+ } else if (tokens.matches("..")) {
+ // No abbreviated reverse steps allowed ...
+ throw new ParsingException(tokens.nextPosition(),
+ "XPath abbreviated reverse steps (e.g., '..') are not supported");
+ } else if (tokens.matches("parent", ":", ":") || tokens.matches("ancestor-or-self", ":", ":")
+ || tokens.matches("preceding-sibling", ":", ":") || tokens.matches("preceding", ":", ":")
+ || tokens.matches("ancestor", ":", ":")) {
+ // No non-abbreviated reverse steps allowed ...
+ throw new ParsingException(
+ tokens.nextPosition(),
+ "XPath non-abbreviated reverse steps (e.g., 'parent::', 'ancestor::', 'ancestor-or-self::', 'preceding-or-sibling::', or 'preceding::') are not supported");
+ } else if (tokens.matches(ANY_VALUE, ":", ANY_VALUE)
+ && tokens.matches(XPathTokenizer.NAME, XPathTokenizer.SYMBOL, XPathTokenizer.NAME)) {
+ // This is probably a forward step with a (qualified) name test ...
+ nodeTest = parseQName(tokens);
+ } else if (tokens.matches(XPathTokenizer.NAME)) {
+ // This is probably a forward step with an unqualified name test ...
+ nodeTest = parseNodeTest(tokens);
+ } else {
+ return null;
+ }
+
+ // Parse the predicates
+ List<Component> predicates = parsePredicates(tokens);
+ return new AxisStep(nodeTest, predicates);
+ }
+
+ protected List<Component> parsePredicates( TokenStream tokens ) {
+ List<Component> predicates = new ArrayList<Component>();
+ while (tokens.canConsume('[')) {
+ predicates.add(parseExpr(tokens));
+ tokens.consume(']');
+ }
+ return predicates;
+ }
+
+ protected FilterStep parseFilterExpr( TokenStream tokens ) {
+ Component primaryExpr = parsePrimaryExpr(tokens);
+ List<Component> predicates = parsePredicates(tokens);
+ return new FilterStep(primaryExpr, predicates);
+ }
+
+ protected Component parsePrimaryExpr( TokenStream tokens ) {
+ if (tokens.matches('(')) {
+ return parseParenthesizedExpr(tokens);
+ }
+ if (tokens.matches('.')) {
+ return parseContextItemExpr(tokens);
+ }
+ if (tokens.matches(XPathTokenizer.QUOTED_STRING)) {
+ return parseStringLiteral(tokens);
+ }
+ if (tokens.matches(ANY_VALUE, "(") || tokens.matches(ANY_VALUE, ":", ANY_VALUE, "(")) {
+ return parseFunctionCall(tokens);
+ }
+ return parseNumericLiteral(tokens);
+ }
+
+ protected ContextItem parseContextItemExpr( TokenStream tokens ) {
+ tokens.consume('.');
+ return new ContextItem();
+ }
+
+ protected ParenthesizedExpression parseParenthesizedExpr( TokenStream tokens ) {
+ tokens.consume('(');
+ if (tokens.canConsume(')')) {
+ return new ParenthesizedExpression();
+ }
+ Component expr = parseExpr(tokens);
+ tokens.consume(')');
+ return new ParenthesizedExpression(expr);
+ }
+
+ protected Literal parseNumericLiteral( TokenStream tokens ) {
+ Position pos = tokens.nextPosition();
+ String sign = "";
+ if (tokens.canConsume('-')) sign = "-";
+ else if (tokens.canConsume('+')) sign = "";
+
+ // Try to parse this value as a number ...
+ ValueFactory<String> stringFactory = context.getValueFactories().getStringFactory();
+ String number = tokens.consume();
+ if (number.indexOf(".") != -1) {
+ String value = sign + number;
+ if (value.endsWith("e") && (tokens.matches('+') || tokens.matches('-'))) {
+ // There's more to the number ...
+ value = value + tokens.consume() + tokens.consume(); // +/-EXP
+ }
+ try {
+ // Convert to a double and then back to a string to get canonical form ...
+ String canonical = stringFactory.create(context.getValueFactories().getDoubleFactory().create(value));
+ return new Literal(canonical);
+ } catch (ValueFormatException e) {
+ String msg = GraphI18n.expectingLiteralAndUnableToParseAsDouble.text(value, pos.getLine(), pos.getColumn());
+ throw new ParsingException(pos, msg);
+ }
+ }
+ // try to parse an a long ...
+ String value = sign + number;
+ try {
+ // Convert to a long and then back to a string to get canonical form ...
+ String canonical = stringFactory.create(context.getValueFactories().getLongFactory().create(value));
+ return new Literal(canonical);
+ } catch (ValueFormatException e) {
+ String msg = GraphI18n.expectingLiteralAndUnableToParseAsLong.text(value, pos.getLine(), pos.getColumn());
+ throw new ParsingException(pos, msg);
+ }
+ }
+
+ protected Literal parseStringLiteral( TokenStream tokens ) {
+ boolean removeQuotes = tokens.matches(XPathTokenizer.QUOTED_STRING);
+ String value = tokens.consume();
+ if (removeQuotes) value = removeQuotes(value);
+ return new Literal(value);
+ }
+
+ protected FunctionCall parseFunctionCall( TokenStream tokens ) {
+ NameTest name = parseQName(tokens);
+ tokens.consume("(");
+ List<Component> args = new ArrayList<Component>();
+ if (!tokens.matches(')')) {
+ do {
+ args.add(parseExprSingle(tokens));
+ } while (tokens.canConsume(","));
+ tokens.consume(")");
+ }
+ return new FunctionCall(name, args);
+ }
+
+ protected Operator parseGeneralComp( TokenStream tokens ) {
+ if (tokens.canConsume("!", "=")) return Operator.NOT_EQUAL_TO;
+ if (tokens.canConsume("=")) return Operator.EQUAL_TO;
+ if (tokens.canConsume("<", "=")) return Operator.LESS_THAN_OR_EQUAL_TO;
+ if (tokens.canConsume(">", "=")) return Operator.GREATER_THAN_OR_EQUAL_TO;
+ if (tokens.canConsume("<")) return Operator.LESS_THAN;
+ if (tokens.canConsume(">")) return Operator.GREATER_THAN;
+ return null;
+ }
+
+ protected NodeTest parseNodeTest( TokenStream tokens ) {
+ KindTest kind = parseKindTest(tokens);
+ if (kind != null) return kind;
+ return parseNameTest(tokens);
+ }
+
+ protected NameTest parseNameTest( TokenStream tokens ) {
+ NameTest wildcard = parseWildcard(tokens);
+ if (wildcard != null) return wildcard;
+ return parseQName(tokens);
+ }
+
+ protected NameTest parseQName( TokenStream tokens ) {
+ String firstPart = parseNCName(tokens);
+ if (tokens.canConsume(':')) {
+ String secondPart = tokens.consume();
+ return new NameTest(firstPart, secondPart);
+ }
+ return new NameTest(null, firstPart);
+ }
+
+ protected String parseNCName( TokenStream tokens ) {
+ String name = tokens.consume();
+ if (!XmlCharacters.isValidNcName(name)) {
+ throw new ParsingException(tokens.previousPosition(), "Expected valid NCName but found " + name);
+ }
+ return name;
+ }
+
+ protected NameTest parseWildcard( TokenStream tokens ) {
+ if (tokens.canConsume('*')) {
+ if (tokens.canConsume(':')) {
+ if (tokens.canConsume('*')) {
+ return new NameTest(null, null);
+ }
+ String localName = tokens.consume();
+ return new NameTest(null, localName);
+ }
+ return new NameTest(null, null);
+ }
+ if (tokens.matches(XPathTokenizer.NAME, XPathTokenizer.SYMBOL, XPathTokenizer.SYMBOL)
+ && tokens.matches(TokenStream.ANY_VALUE, ":", "*")) {
+ String prefix = tokens.consume();
+ tokens.consume(':');
+ tokens.consume('*');
+ return new NameTest(prefix, null);
+ }
+ return null;
+ }
+
+ protected NameTest parseItemType( TokenStream tokens ) {
+ return parseQName(tokens);
+ }
+
+ protected NameTest parseAtomicType( TokenStream tokens ) {
+ return parseQName(tokens);
+ }
+
+ protected KindTest parseKindTest( TokenStream tokens ) {
+ KindTest result = parseAnyKindTest(tokens);
+ if (result == null) result = parseDocumentTest(tokens);
+ if (result == null) result = parseElementTest(tokens);
+ if (result == null) result = parseAttributeTest(tokens);
+ if (result == null) result = parseSchemaElementTest(tokens);
+ if (result == null) result = parseSchemaAttributeTest(tokens);
+ if (result == null) result = parsePITest(tokens);
+ if (result == null) result = parseCommentTest(tokens);
+ if (result == null) result = parseTextTest(tokens);
+ return result;
+ }
+
+ protected AnyKindTest parseAnyKindTest( TokenStream tokens ) {
+ if (tokens.canConsume("node", "(", ")")) {
+ return new AnyKindTest();
+ }
+ return null;
+ }
+
+ protected ProcessingInstructionTest parsePITest( TokenStream tokens ) {
+ if (tokens.canConsume("processing-instruction", "(")) {
+ if (tokens.canConsume(")")) return new ProcessingInstructionTest(null);
+ String nameOrStringLiteral = tokens.consume();
+ tokens.consume(")");
+ return new ProcessingInstructionTest(nameOrStringLiteral);
+ }
+ return null;
+ }
+
+ protected CommentTest parseCommentTest( TokenStream tokens ) {
+ if (tokens.canConsume("comment", "(", ")")) {
+ return new CommentTest();
+ }
+ return null;
+ }
+
+ protected TextTest parseTextTest( TokenStream tokens ) {
+ if (tokens.canConsume("text", "(", ")")) {
+ return new TextTest();
+ }
+ return null;
+ }
+
+ protected DocumentTest parseDocumentTest( TokenStream tokens ) {
+ if (tokens.canConsume("document-node", "(")) {
+ // Document test ...
+ ElementTest elementTest = parseElementTest(tokens);
+ DocumentTest result = null;
+ if (elementTest != null) {
+ result = new DocumentTest(elementTest);
+ } else {
+ SchemaElementTest schemaTest = parseSchemaElementTest(tokens);
+ result = schemaTest != null ? new DocumentTest(schemaTest) : null;
+ }
+ tokens.consume(")");
+ return result;
+ }
+ return null;
+ }
+
+ protected ElementTest parseElementTest( TokenStream tokens ) {
+ if (tokens.canConsume("element", "(")) {
+ if (tokens.canConsume(")") || tokens.canConsume("*", ")")) {
+ return new ElementTest(new NameTest(null, null), new NameTest(null, null));
+ }
+ ElementTest result = null;
+ NameTest elementName = parseNameTest(tokens);
+ if (tokens.canConsume(",")) {
+ NameTest typeName = parseNameTest(tokens);
+ result = new ElementTest(elementName, typeName);
+ } else {
+ result = new ElementTest(elementName, new NameTest(null, null));
+ }
+ tokens.consume(")");
+ return result;
+ }
+ return null;
+ }
+
+ protected SchemaElementTest parseSchemaElementTest( TokenStream tokens ) {
+ if (tokens.canConsume("schema-element", "(")) {
+ NameTest elementDeclarationName = parseNameTest(tokens);
+ SchemaElementTest result = new SchemaElementTest(elementDeclarationName);
+ tokens.consume(")");
+ return result;
+ }
+ return null;
+ }
+
+ protected AttributeTest parseAttributeTest( TokenStream tokens ) {
+ if (tokens.canConsume("attribute", "(")) {
+ if (tokens.canConsume(")") || tokens.canConsume("*", ")")) {
+ return new AttributeTest(new NameTest(null, null), new NameTest(null, null));
+ }
+ AttributeTest result = null;
+ NameTest attributeName = parseNameTest(tokens);
+ if (tokens.canConsume(",")) {
+ NameTest typeName = parseNameTest(tokens);
+ result = new AttributeTest(attributeName, typeName);
+ } else {
+ result = new AttributeTest(attributeName, new NameTest(null, null));
+ }
+ tokens.consume(")");
+ return result;
+ }
+ return null;
+ }
+
+ protected SchemaAttributeTest parseSchemaAttributeTest( TokenStream tokens ) {
+ if (tokens.canConsume("schema-attribute", "(")) {
+ NameTest attributeDeclarationName = parseNameTest(tokens);
+ SchemaAttributeTest result = new SchemaAttributeTest(attributeDeclarationName);
+ tokens.consume(")");
+ return result;
+ }
+ return null;
+ }
+
+ protected void parseSingleType( TokenStream tokens ) {
+ }
+
+ protected void parseSequenceType( TokenStream tokens ) {
+ }
+
+ /**
+ * Remove any leading and trailing single-quotes or double-quotes from the supplied text.
+ *
+ * @param text the input text; may not be null
+ * @return the text without leading and trailing quotes, or <code>text</code> if there were no square brackets or quotes
+ */
+ protected String removeQuotes( String text ) {
+ return text.replaceFirst("^['\"]+", "").replaceAll("['\"]+$", "");
+ }
+ }
+
+ /**
+ * A {@link TokenStream.Tokenizer} implementation that parses single- and double-quoted strings, symbols, words consisting of
+ * {@link TokenStream.CharacterStream#isNextValidXmlNcNameCharacter() NCName}s (as defined by the <a
+ * href="http://www.w3.org/TR/REC-xml-names/#NT-NCName">Namespaces in XML 1.0</a> specification), XPath comments,and
+ * {@link #OTHER other} single-character tokens. Quoted phrases are delimited by single-quote and double-quote characters
+ * (which may be escaped within the quote). XPath comments begin with a "(:" and end with a ":)".
+ */
+ public static class XPathTokenizer implements TokenStream.Tokenizer {
+ /**
+ * The token type for tokens that represent an unquoted string containing a character sequence made up of non-whitespace
+ * and non-symbol characters.
+ */
+ public static final int NAME = 2 << 0;
+ /**
+ * The token type for tokens that consist of an individual "symbol" character. The set of characters includes:
+ * <code>(){}*.,;+%?$!<>|=:-[]^/\#@</code>
+ */
+ public static final int SYMBOL = 2 << 1;
+ /**
+ * The token type for tokens that consist of all the characters within single-quotes, double-quotes, or square brackets.
+ */
+ public static final int QUOTED_STRING = 2 << 2;
+ /**
+ * The token type for tokens that consist of all the characters between "(:" and ":)".
+ */
+ public static final int COMMENT = 2 << 3;
+ /**
+ * The token type for tokens that consist of single characters that are not a {@link #SYMBOL}, valid {@link #NAME}, or
+ * {@link #QUOTED_STRING}.
+ */
+ public static final int OTHER = 2 << 4;
+
+ private final boolean useComments;
+
+ public XPathTokenizer( boolean useComments ) {
+ this.useComments = useComments;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.jboss.dna.common.text.TokenStream.Tokenizer#tokenize(CharacterStream, Tokens)
+ */
+ public void tokenize( CharacterStream input,
+ Tokens tokens ) throws ParsingException {
+ while (input.hasNext()) {
+ char c = input.next();
+ switch (c) {
+ case ' ':
+ case '\t':
+ case '\n':
+ case '\r':
+ // Just skip these whitespace characters ...
+ break;
+ case ')':
+ case '{':
+ case '}':
+ case '*':
+ case '.':
+ case ',':
+ case ';':
+ case '+':
+ case '%':
+ case '?':
+ case '$':
+ case '!':
+ case '<':
+ case '>':
+ case '|':
+ case '=':
+ case ':':
+ case '-':
+ case '[':
+ case ']':
+ case '^':
+ case '/':
+ case '\\':
+ case '#':
+ case '@':
+ tokens.addToken(input.position(), input.index(), input.index() + 1, SYMBOL);
+ break;
+ case '\'':
+ case '\"':
+ int startIndex = input.index();
+ char closingChar = c;
+ Position pos = input.position();
+ boolean foundClosingQuote = false;
+ while (input.hasNext()) {
+ c = input.next();
+ if (c == closingChar && input.isNext(closingChar)) {
+ c = input.next(); // consume the next closeChar since it is escaped
+ } else if (c == closingChar) {
+ foundClosingQuote = true;
+ break;
+ }
+ }
+ if (!foundClosingQuote) {
+ String msg = CommonI18n.noMatchingDoubleQuoteFound.text(pos.getLine(), pos.getColumn());
+ if (closingChar == '\'') {
+ msg = CommonI18n.noMatchingSingleQuoteFound.text(pos.getLine(), pos.getColumn());
+ }
+ throw new ParsingException(pos, msg);
+ }
+ int endIndex = input.index() + 1; // beyond last character read
+ tokens.addToken(pos, startIndex, endIndex, QUOTED_STRING);
+ break;
+ case '(':
+ startIndex = input.index();
+ if (input.isNext(':')) {
+ // This is a comment ...
+ pos = input.position();
+ while (input.hasNext() && !input.isNext(':', ')')) {
+ c = input.next();
+ }
+ if (input.hasNext()) input.next(); // consume the ':'
+ if (input.hasNext()) input.next(); // consume the ')'
+ if (useComments) {
+ endIndex = input.index() + 1; // the token will include the closing ':' and ')' characters
+ tokens.addToken(pos, startIndex, endIndex, COMMENT);
+ }
+ } else {
+ tokens.addToken(input.position(), input.index(), input.index() + 1, SYMBOL);
+ break;
+ }
+ break;
+ default:
+ startIndex = input.index();
+ pos = input.position();
+ // Read as long as there is a valid XML character ...
+ int tokenType = (XmlCharacters.isValidNcNameStart(c)) ? NAME : OTHER;
+ while (input.isNextValidXmlNcNameCharacter()) {
+ c = input.next();
+ }
+ endIndex = input.index() + 1; // beyond last character that was included
+ tokens.addToken(pos, startIndex, endIndex, tokenType);
+ }
+ }
+ }
+ }
+}
Property changes on: trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/xpath/XPathParser.java
___________________________________________________________________
Name: svn:keywords
+ Id Revision
Name: svn:eol-style
+ LF
Added: trunk/dna-jcr/src/test/java/org/jboss/dna/jcr/xpath/XPathParserTest.java
===================================================================
--- trunk/dna-jcr/src/test/java/org/jboss/dna/jcr/xpath/XPathParserTest.java (rev 0)
+++ trunk/dna-jcr/src/test/java/org/jboss/dna/jcr/xpath/XPathParserTest.java 2009-10-03 04:07:41 UTC (rev 1285)
@@ -0,0 +1,867 @@
+/*
+ * JBoss DNA (http://www.jboss.org/dna)
+ * 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.
+ * See the AUTHORS.txt file in the distribution for a full listing of
+ * individual contributors.
+ *
+ * JBoss DNA is free software. Unless otherwise indicated, all code in JBoss DNA
+ * is licensed to you 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.
+ *
+ * JBoss DNA 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 software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.dna.jcr.xpath;
+
+import static org.hamcrest.core.Is.is;
+import static org.hamcrest.core.IsInstanceOf.instanceOf;
+import static org.hamcrest.core.IsNull.notNullValue;
+import static org.hamcrest.core.IsNull.nullValue;
+import static org.junit.Assert.assertThat;
+import static org.junit.Assert.fail;
+import java.util.Arrays;
+import java.util.List;
+import org.jboss.dna.common.text.ParsingException;
+import org.jboss.dna.common.text.TokenStream;
+import org.jboss.dna.common.text.TokenStream.Tokenizer;
+import org.jboss.dna.graph.ExecutionContext;
+import org.jboss.dna.graph.query.model.Operator;
+import org.jboss.dna.jcr.xpath.XPath.AnyKindTest;
+import org.jboss.dna.jcr.xpath.XPath.AttributeNameTest;
+import org.jboss.dna.jcr.xpath.XPath.AttributeTest;
+import org.jboss.dna.jcr.xpath.XPath.AxisStep;
+import org.jboss.dna.jcr.xpath.XPath.CommentTest;
+import org.jboss.dna.jcr.xpath.XPath.Component;
+import org.jboss.dna.jcr.xpath.XPath.ContextItem;
+import org.jboss.dna.jcr.xpath.XPath.DescendantOrSelf;
+import org.jboss.dna.jcr.xpath.XPath.DocumentTest;
+import org.jboss.dna.jcr.xpath.XPath.ElementTest;
+import org.jboss.dna.jcr.xpath.XPath.FilterStep;
+import org.jboss.dna.jcr.xpath.XPath.FunctionCall;
+import org.jboss.dna.jcr.xpath.XPath.Literal;
+import org.jboss.dna.jcr.xpath.XPath.NameTest;
+import org.jboss.dna.jcr.xpath.XPath.NodeTest;
+import org.jboss.dna.jcr.xpath.XPath.ParenthesizedExpression;
+import org.jboss.dna.jcr.xpath.XPath.PathExpression;
+import org.jboss.dna.jcr.xpath.XPath.SchemaAttributeTest;
+import org.jboss.dna.jcr.xpath.XPath.SchemaElementTest;
+import org.jboss.dna.jcr.xpath.XPath.StepExpression;
+import org.jboss.dna.jcr.xpath.XPath.TextTest;
+import org.jboss.dna.jcr.xpath.XPathParser.XPathTokenizer;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ *
+ */
+public class XPathParserTest {
+
+ private ExecutionContext context;
+ private XPathParser.Parser parser;
+
+ @Before
+ public void beforeEach() {
+ context = new ExecutionContext();
+ parser = new XPathParser.Parser(context);
+ }
+
+ @After
+ public void afterEach() {
+ parser = null;
+ }
+
+ @Test
+ public void shouldParseXPathExpressions() {
+ assertParsable("/jcr:root/a/b/c");
+ assertParsable("/jcr:root/a/b/c[*]");
+ assertParsable("/jcr:root/some[1]/element(nodes, my:type)[1]");
+ assertParsable("//element(*,my:type)");
+ assertParsable("//element(*,my:type)[@jcr:title='something' and @globalProperty='something else']");
+ assertParsable("//element(*,my:type)[@jcr:title | @globalProperty]");
+ assertParsable("//element(*, my:type) order by @my:title");
+ assertParsable("//element(*, my:type) [jcr:contains(., 'jcr')] order by jcr:score() descending");
+ assertParsable("//element(*, employee)[@secretary and @assistant]");
+ }
+
+ @Test
+ public void shouldParseXPathExpressionsThatCombineSeparateExpressions() {
+ assertParsable("/jcr:root/a/b/c and /jcr:root/c/d/e");
+ assertParsable("/jcr:root/a/b/c and /jcr:root/c/d/e or /jcr:root/f/g/h");
+ }
+
+ @Test
+ public void shouldFailToParseInvalidXPathExpressions() {
+ assertNotParsable("//"); // http://www.w3.org/XML/2007/qt-errata/xpath20-errata.html#E3
+ }
+
+ // ----------------------------------------------------------------------------------------------------------------
+ // Path expression
+ // ----------------------------------------------------------------------------------------------------------------
+
+ @Test
+ public void shouldParsePathExpressionWithAbbreviatedDescendantOrSelfWithNameTestAfter() {
+ assertThat(parser.parsePathExpr(tokenize("//b:c")), is(pathExpr(descendantOrSelf(), axisStep(nameTest("b", "c")))));
+ }
+
+ @Test
+ public void shouldParsePathExpressionWithAbbreviatedDescendantOrSelfWithRelativeNamePathPredicate() {
+ assertThat(parser.parsePathExpr(tokenize("//.[c]")), is(pathExpr(descendantOrSelf(),
+ filterStep(contextItem(),
+ relativePathExpr(axisStep(nameTest("c")))))));
+ }
+
+ @Test
+ public void shouldParsePathExpressionWithAbbreviatedDescendantOrSelfWithRelativeNumericLiteralPredicate() {
+ assertThat(parser.parsePathExpr(tokenize("//.[3]")), is(pathExpr(descendantOrSelf(),
+ filterStep(contextItem(),
+ relativePathExpr(filterStep(literal("3")))))));
+ }
+
+ // ----------------------------------------------------------------------------------------------------------------
+ // Relative path expression
+ // ----------------------------------------------------------------------------------------------------------------
+
+ @Test
+ public void shouldParseRelativePathExpressionWithAbbreviatedDescendantOrSelfWithNameTestAfter() {
+ assertThat(parser.parseRelativePathExpr(tokenize("a//b:c")), is(relativePathExpr(axisStep(nameTest("a")),
+ descendantOrSelf(),
+ axisStep(nameTest("b", "c")))));
+ }
+
+ @Test
+ public void shouldParseRelativePathExpressionWithAbbreviatedDescendantOrSelfAtEnd() {
+ assertThat(parser.parseRelativePathExpr(tokenize("a//")),
+ is(relativePathExpr(axisStep(nameTest("a")), descendantOrSelf())));
+ }
+
+ @Test
+ public void shouldParseRelativePathExpressionWithAbbreviatedDescendantOrSelfWithRelativeNamePathPredicate() {
+ assertThat(parser.parseRelativePathExpr(tokenize("a//.[c]")),
+ is(relativePathExpr(axisStep(nameTest("a")),
+ descendantOrSelf(),
+ filterStep(contextItem(), relativePathExpr(axisStep(nameTest("c")))))));
+ }
+
+ @Test
+ public void shouldParseRelativePathExpressionWithAbbreviatedDescendantOrSelfWithRelativeNumericLiteralPredicate() {
+ assertThat(parser.parseRelativePathExpr(tokenize("a//.[3]")),
+ is(relativePathExpr(axisStep(nameTest("a")),
+ descendantOrSelf(),
+ filterStep(contextItem(), relativePathExpr(filterStep(literal("3")))))));
+ }
+
+ // ----------------------------------------------------------------------------------------------------------------
+ // Step Expression
+ // ----------------------------------------------------------------------------------------------------------------
+
+ @Test
+ public void shouldParseStepExpressionFromParenthesizedLiteral() {
+ assertThat(parser.parseStepExpr(tokenize("('foo')")),
+ is((StepExpression)filterStep(paren(relativePathExpr(filterStep(literal("foo")))))));
+ }
+
+ @Test
+ public void shouldParseStepExpressionFromQuotedStringLiteral() {
+ assertThat(parser.parseStepExpr(tokenize("'foo'")), is((StepExpression)filterStep(literal("foo"))));
+ }
+
+ @Test
+ public void shouldParseStepExpressionFromFunctionCallWithUnqualifiedName() {
+ assertThat(parser.parseStepExpr(tokenize("element(*,*)")),
+ is((StepExpression)filterStep(functionCall(nameTest("element"),
+ relativePathExpr(axisStep(wildcard())),
+ relativePathExpr(axisStep(wildcard()))))));
+ }
+
+ @Test
+ public void shouldParseStepExpressionFromFunctionCallWithQualifiedName() {
+ assertThat(parser.parseStepExpr(tokenize("foo:bar(*)")),
+ is((StepExpression)filterStep(functionCall(nameTest("foo", "bar"), relativePathExpr(axisStep(wildcard()))))));
+ }
+
+ @Test
+ public void shouldParseStepExpressionFromQualifiedNameWithPredicate() {
+ assertThat(parser.parseStepExpr(tokenize("foo:bar[3]")),
+ is((StepExpression)axisStep(nameTest("foo", "bar"), relativePathExpr(filterStep(literal("3"))))));
+ }
+
+ // ----------------------------------------------------------------------------------------------------------------
+ // Axis Step - attribute
+ // ----------------------------------------------------------------------------------------------------------------
+
+ @Test
+ public void shouldParseAxisStepFromAttributeWithNoPrefix() {
+ assertThat(parser.parseAxisStep(tokenize("@foo")), is(axisStep(attributeNameTest(nameTest("foo")))));
+ }
+
+ @Test
+ public void shouldParseAxisStepFromAttributeWithPrefix() {
+ assertThat(parser.parseAxisStep(tokenize("@foo:bar")), is(axisStep(attributeNameTest(nameTest("foo", "bar")))));
+ }
+
+ @Test( expected = ParsingException.class )
+ public void shouldFailToParseAxisStepFromInvalidAttributeName() {
+ parser.parseAxisStep(tokenize("@3:invalidName"));
+ }
+
+ // ----------------------------------------------------------------------------------------------------------------
+ // Axis Step - name
+ // ----------------------------------------------------------------------------------------------------------------
+
+ @Test
+ public void shouldParseAxisStepFromNameWithNoPrefix() {
+ assertThat(parser.parseAxisStep(tokenize("foo")), is(axisStep(nameTest("foo"))));
+ }
+
+ @Test
+ public void shouldParseAxisStepFromNameWithPrefix() {
+ assertThat(parser.parseAxisStep(tokenize("foo:bar")), is(axisStep(nameTest("foo", "bar"))));
+ }
+
+ @Test
+ public void shouldReturnNullFromParseAxisStepIfInvalidName() {
+ assertThat(parser.parseAxisStep(tokenize("3:invalidName")), is(nullValue()));
+ }
+
+ // ----------------------------------------------------------------------------------------------------------------
+ // Axis Step - wildcard
+ // ----------------------------------------------------------------------------------------------------------------
+
+ @Test
+ public void shouldParseAxisStepFromWildcard() {
+ assertThat(parser.parseAxisStep(tokenize("*")), is(axisStep(wildcard())));
+ }
+
+ @Test
+ public void shouldParseAxisStepFromWildcardPrefixAndNonWildcardLocalName() {
+ assertThat(parser.parseAxisStep(tokenize("*:foo")), is(axisStep(nameTest(null, "foo"))));
+ }
+
+ @Test
+ public void shouldParseAxisStepFromWithPrefixAndWildcardLocalName() {
+ assertThat(parser.parseAxisStep(tokenize("foo:*")), is(axisStep(nameTest("foo", null))));
+ }
+
+ @Test
+ public void shouldParseAxisStepFromWildcardPrefixAndNonWildcardLocalNameWithPredicates() {
+ assertThat(parser.parseAxisStep(tokenize("*:name[3]")), is(axisStep(nameTest(null, "name"),
+ relativePathExpr(filterStep(literal("3"))))));
+ }
+
+ @Test
+ public void shouldParseAxisStepFromWildcardLocalNameWithPredicates() {
+ assertThat(parser.parseAxisStep(tokenize("*[3]")), is(axisStep(wildcard(), relativePathExpr(filterStep(literal("3"))))));
+ }
+
+ @Test
+ public void shouldParseAxisStepFromWildcardPrefixAndLocalNameWithPredicates() {
+ assertThat(parser.parseAxisStep(tokenize("*:*[3]")), is(axisStep(wildcard(), relativePathExpr(filterStep(literal("3"))))));
+ }
+
+ // ----------------------------------------------------------------------------------------------------------------
+ // Axis Step - self::, child::, descendant::, descendant-or-self::, following::, following-sibling::, namespace::
+ // ----------------------------------------------------------------------------------------------------------------
+
+ @Test( expected = ParsingException.class )
+ public void shouldFailToParseNonAbbreviatedSelfAxis() {
+ parser.parseAxisStep(tokenize("self::x"));
+ }
+
+ @Test( expected = ParsingException.class )
+ public void shouldFailToParseNonAbbreviatedChildAxis() {
+ parser.parseAxisStep(tokenize("child::x"));
+ }
+
+ @Test( expected = ParsingException.class )
+ public void shouldFailToParseNonAbbreviatedDescendantAxis() {
+ parser.parseAxisStep(tokenize("descendant::x"));
+ }
+
+ @Test( expected = ParsingException.class )
+ public void shouldFailToParseNonAbbreviatedDescendantOrSelfAxis() {
+ parser.parseAxisStep(tokenize("descendant-or-self::x"));
+ }
+
+ @Test( expected = ParsingException.class )
+ public void shouldFailToParseNonAbbreviatedFollowingAxis() {
+ parser.parseAxisStep(tokenize("following::x"));
+ }
+
+ @Test( expected = ParsingException.class )
+ public void shouldFailToParseNonAbbreviatedFollowingSiblingAxis() {
+ parser.parseAxisStep(tokenize("following-sibling::x"));
+ }
+
+ @Test( expected = ParsingException.class )
+ public void shouldFailToParseNonAbbreviatedNamespaceAxis() {
+ parser.parseAxisStep(tokenize("namespace::x"));
+ }
+
+ // ----------------------------------------------------------------------------------------------------------------
+ // Axis Step - parent::, ancestor::, ancestor-or-self::, preceding::, preceding-sibling::
+ // ----------------------------------------------------------------------------------------------------------------
+
+ @Test( expected = ParsingException.class )
+ public void shouldFailToParseNonAbbreviatedParentAxis() {
+ parser.parseAxisStep(tokenize("parent::x"));
+ }
+
+ @Test( expected = ParsingException.class )
+ public void shouldFailToParseNonAbbreviatedAncestorAxis() {
+ parser.parseAxisStep(tokenize("ancestor::x"));
+ }
+
+ @Test( expected = ParsingException.class )
+ public void shouldFailToParseNonAbbreviatedAncestorOrSelfAxis() {
+ parser.parseAxisStep(tokenize("ancestor-or-self::x"));
+ }
+
+ @Test( expected = ParsingException.class )
+ public void shouldFailToParseNonAbbreviatedPrecedingAxis() {
+ parser.parseAxisStep(tokenize("preceding::x"));
+ }
+
+ @Test( expected = ParsingException.class )
+ public void shouldFailToParseNonAbbreviatedPrecedingSiblingAxis() {
+ parser.parseAxisStep(tokenize("preceding-sibling::x"));
+ }
+
+ // ----------------------------------------------------------------------------------------------------------------
+ // Predicates
+ // ----------------------------------------------------------------------------------------------------------------
+
+ @Test
+ public void shouldParsePredicatesWhenThereIsOnlyOnePredicate() {
+ assertThat(parser.parsePredicates(tokenize("[foo]")), is(predicates(relativePathExpr(axisStep(nameTest("foo"))))));
+ }
+
+ @Test
+ public void shouldParsePredicatesWhenThereAreMultiplePredicates() {
+ assertThat(parser.parsePredicates(tokenize("['foo']['bar']")),
+ is(predicates(relativePathExpr(filterStep(literal("foo"))), relativePathExpr(filterStep(literal("bar"))))));
+ assertThat(parser.parsePredicates(tokenize("[foo][bar]")), is(predicates(relativePathExpr(axisStep(nameTest("foo"))),
+ relativePathExpr(axisStep(nameTest("bar"))))));
+ }
+
+ // ----------------------------------------------------------------------------------------------------------------
+ // Context item
+ // ----------------------------------------------------------------------------------------------------------------
+
+ @Test
+ public void shouldParseContextItemExpr() {
+ assertThat(parser.parseContextItemExpr(tokenize(".")), is(new ContextItem()));
+ }
+
+ // ----------------------------------------------------------------------------------------------------------------
+ // Parenthesized expression
+ // ----------------------------------------------------------------------------------------------------------------
+
+ @Test
+ public void shouldParseParenthesizedExpression() {
+ assertThat(parser.parseParenthesizedExpr(tokenize("('foo')")), is(paren(relativePathExpr(filterStep(literal("foo"))))));
+ }
+
+ // ----------------------------------------------------------------------------------------------------------------
+ // Number literal
+ // ----------------------------------------------------------------------------------------------------------------
+
+ @Test
+ public void shouldParseNumberLiteralContainingUnquotedIntegralValuesIntoCanonicalStringRepresentation() {
+ assertThat(parser.parseNumericLiteral(tokenize("1")), is(literal("1")));
+ assertThat(parser.parseNumericLiteral(tokenize("-1")), is(literal("-1")));
+ assertThat(parser.parseNumericLiteral(tokenize("0")), is(literal("0")));
+ assertThat(parser.parseNumericLiteral(tokenize("+1001")), is(literal("1001")));
+ }
+
+ @Test
+ public void shouldParseNumberLiteralContainingUnquotedDecimalValuesIntoCanonicalStringRepresentation() {
+ assertThat(parser.parseNumericLiteral(tokenize("1.2")), is(literal("1.2")));
+ assertThat(parser.parseNumericLiteral(tokenize("-1.2")), is(literal("-1.2")));
+ assertThat(parser.parseNumericLiteral(tokenize("0.2")), is(literal("0.2")));
+ assertThat(parser.parseNumericLiteral(tokenize("+1001.2")), is(literal("1001.2")));
+ assertThat(parser.parseNumericLiteral(tokenize("1.2e10")), is(literal("1.2E10")));
+ assertThat(parser.parseNumericLiteral(tokenize("-1.2e10")), is(literal("-1.2E10")));
+ assertThat(parser.parseNumericLiteral(tokenize("0.2e10")), is(literal("2.0E9")));
+ assertThat(parser.parseNumericLiteral(tokenize("1.2e+10")), is(literal("1.2E10")));
+ assertThat(parser.parseNumericLiteral(tokenize("-1.2e+10")), is(literal("-1.2E10")));
+ assertThat(parser.parseNumericLiteral(tokenize("0.2e+10")), is(literal("2.0E9")));
+ assertThat(parser.parseNumericLiteral(tokenize("1.2e-10")), is(literal("1.2E-10")));
+ assertThat(parser.parseNumericLiteral(tokenize("-1.2e-10")), is(literal("-1.2E-10")));
+ assertThat(parser.parseNumericLiteral(tokenize("0.2e-10")), is(literal("2.0E-11")));
+ }
+
+ // ----------------------------------------------------------------------------------------------------------------
+ // String literal
+ // ----------------------------------------------------------------------------------------------------------------
+
+ @Test
+ public void shouldParseStringLiteral() {
+ assertThat(parser.parseStringLiteral(tokenize("one")), is(literal("one")));
+ assertThat(parser.parseStringLiteral(tokenize("'one'")), is(literal("one")));
+ assertThat(parser.parseStringLiteral(tokenize("'one word as a quote'")), is(literal("one word as a quote")));
+ }
+
+ // ----------------------------------------------------------------------------------------------------------------
+ // Function call
+ // ----------------------------------------------------------------------------------------------------------------
+
+ @Test
+ public void shouldParseFunctionCallWithZeroParameters() {
+ FunctionCall func = parser.parseFunctionCall(tokenize("a()"));
+ assertThat(func, is(notNullValue()));
+ assertThat(func.getName(), is(nameTest("a")));
+ assertThat(func.getParameters().isEmpty(), is(true));
+ }
+
+ @Test
+ public void shouldParseFunctionCallWithOneQuotedStringLiteralParameter() {
+ FunctionCall func = parser.parseFunctionCall(tokenize("a('foo')"));
+ assertThat(func, is(notNullValue()));
+ assertThat(func.getName(), is(nameTest("a")));
+ assertThat(func.getParameters().size(), is(1));
+ assertThat(func.getParameters().get(0), is((Component)relativePathExpr(filterStep(literal("foo")))));
+ }
+
+ @Test
+ public void shouldParseFunctionCallWithOneUnquotedStringLiteralParameter() {
+ FunctionCall func = parser.parseFunctionCall(tokenize("a(foo)"));
+ assertThat(func, is(notNullValue()));
+ assertThat(func.getName(), is(nameTest("a")));
+ assertThat(func.getParameters().size(), is(1));
+ assertThat(func.getParameters().get(0), is((Component)relativePathExpr(axisStep(nameTest("foo")))));
+ }
+
+ // ----------------------------------------------------------------------------------------------------------------
+ // General comparison
+ // ----------------------------------------------------------------------------------------------------------------
+
+ @Test
+ public void shouldParseGeneralComp() {
+ assertThat(parser.parseGeneralComp(tokenize("!=")), is(Operator.NOT_EQUAL_TO));
+ assertThat(parser.parseGeneralComp(tokenize("=")), is(Operator.EQUAL_TO));
+ assertThat(parser.parseGeneralComp(tokenize("<")), is(Operator.LESS_THAN));
+ assertThat(parser.parseGeneralComp(tokenize("<=")), is(Operator.LESS_THAN_OR_EQUAL_TO));
+ assertThat(parser.parseGeneralComp(tokenize(">")), is(Operator.GREATER_THAN));
+ assertThat(parser.parseGeneralComp(tokenize(">=")), is(Operator.GREATER_THAN_OR_EQUAL_TO));
+ assertThat(parser.parseGeneralComp(tokenize("<5")), is(Operator.LESS_THAN));
+ assertThat(parser.parseGeneralComp(tokenize(">5")), is(Operator.GREATER_THAN));
+ }
+
+ @Test
+ public void shouldReturnNullFromParseGeneralCompIfOperatorPatternIsNotFound() {
+ assertThat(parser.parseGeneralComp(tokenize("name")), is(nullValue()));
+ assertThat(parser.parseGeneralComp(tokenize("+")), is(nullValue()));
+ assertThat(parser.parseGeneralComp(tokenize("!+")), is(nullValue()));
+ }
+
+ // ----------------------------------------------------------------------------------------------------------------
+ // Name
+ // ----------------------------------------------------------------------------------------------------------------
+
+ @Test
+ public void shouldParseName() {
+ assertThat(parser.parseNameTest(tokenize("*")), is(wildcard()));
+ assertThat(parser.parseNameTest(tokenize("*:*")), is(wildcard()));
+ assertThat(parser.parseNameTest(tokenize("*:name")), is(nameTest(null, "name")));
+ assertThat(parser.parseNameTest(tokenize("name:*")), is(nameTest("name", null)));
+ assertThat(parser.parseNameTest(tokenize("abc")), is(nameTest("abc")));
+ assertThat(parser.parseNameTest(tokenize("abc:def")), is(nameTest("abc", "def")));
+ }
+
+ @Test( expected = ParsingException.class )
+ public void shouldFailToParseNameIfNotValidWildcardOrQName() {
+ parser.parseNameTest(tokenize("3ABC:def"));
+ }
+
+ // ----------------------------------------------------------------------------------------------------------------
+ // QName
+ // ----------------------------------------------------------------------------------------------------------------
+
+ @Test
+ public void shouldParseQName() {
+ assertThat(parser.parseQName(tokenize("abc")), is(nameTest("abc")));
+ assertThat(parser.parseQName(tokenize("abc:def")), is(nameTest("abc", "def")));
+ }
+
+ @Test( expected = ParsingException.class )
+ public void shouldFailToParseQNameIfStartsWithDigit() {
+ parser.parseNCName(tokenize("3ABC:def"));
+ }
+
+ // ----------------------------------------------------------------------------------------------------------------
+ // NCName
+ // ----------------------------------------------------------------------------------------------------------------
+
+ @Test
+ public void shouldParseNCName() {
+ assertThat(parser.parseNCName(tokenize("ABCDEFGHIJKLMNOPQRSTUVWXYZ")), is("ABCDEFGHIJKLMNOPQRSTUVWXYZ"));
+ assertThat(parser.parseNCName(tokenize("abcdefghijklmnopqrstuvwxyz")), is("abcdefghijklmnopqrstuvwxyz"));
+ assertThat(parser.parseNCName(tokenize("a0123456789")), is("a0123456789"));
+ assertThat(parser.parseNCName(tokenize("a_-3b")), is("a_-3b"));
+ assertThat(parser.parseNCName(tokenize("abc:def")), is("abc"));
+ }
+
+ @Test( expected = ParsingException.class )
+ public void shouldFailToParseNCNameIfStartsWithDigit() {
+ parser.parseNCName(tokenize("3ABC"));
+ }
+
+ // ----------------------------------------------------------------------------------------------------------------
+ // wildcard
+ // ----------------------------------------------------------------------------------------------------------------
+
+ @Test
+ public void shouldParseWildcard() {
+ assertThat(parser.parseWildcard(tokenize("*")), is(wildcard()));
+ assertThat(parser.parseWildcard(tokenize("*:*")), is(wildcard()));
+ assertThat(parser.parseWildcard(tokenize("*:name")), is(nameTest(null, "name")));
+ assertThat(parser.parseWildcard(tokenize("name:*")), is(nameTest("name", null)));
+ }
+
+ @Test
+ public void shouldReturnNullFromParseWildcardIfNotWildcard() {
+ assertThat(parser.parseWildcard(tokenize("name")), is(nullValue()));
+ assertThat(parser.parseWildcard(tokenize("name:foo")), is(nullValue()));
+ }
+
+ // ----------------------------------------------------------------------------------------------------------------
+ // kind test
+ // ----------------------------------------------------------------------------------------------------------------
+
+ @Test
+ public void shouldParseKindTest() {
+ assertThat(parser.parseKindTest(tokenize("node()")), is(instanceOf(AnyKindTest.class)));
+ assertThat(parser.parseKindTest(tokenize("comment()")), is(instanceOf(CommentTest.class)));
+ assertThat(parser.parseKindTest(tokenize("text()")), is(instanceOf(TextTest.class)));
+ assertThat(parser.parseKindTest(tokenize("document-node(element(foo:bar))")), is(instanceOf(DocumentTest.class)));
+ assertThat(parser.parseKindTest(tokenize("element(foo:bar)")), is(instanceOf(ElementTest.class)));
+ assertThat(parser.parseKindTest(tokenize("schema-element(foo:bar)")), is(instanceOf(SchemaElementTest.class)));
+ assertThat(parser.parseKindTest(tokenize("attribute(foo:bar)")), is(instanceOf(AttributeTest.class)));
+ assertThat(parser.parseKindTest(tokenize("schema-attribute(foo:bar)")), is(instanceOf(SchemaAttributeTest.class)));
+ }
+
+ // ----------------------------------------------------------------------------------------------------------------
+ // node
+ // ----------------------------------------------------------------------------------------------------------------
+
+ @Test
+ public void shouldParseAnyKindTest() {
+ assertThat(parser.parseAnyKindTest(tokenize("node()")), is(notNullValue()));
+ }
+
+ @Test
+ public void shouldReturnNullFromParseAnyKindTestIfNotFollowedByOpenAndCloseParenthesis() {
+ assertThat(parser.parseAnyKindTest(tokenize("node x )")), is(nullValue()));
+ assertThat(parser.parseAnyKindTest(tokenize("node(x )")), is(nullValue()));
+ assertThat(parser.parseAnyKindTest(tokenize("node(x")), is(nullValue()));
+ }
+
+ // ----------------------------------------------------------------------------------------------------------------
+ // comment
+ // ----------------------------------------------------------------------------------------------------------------
+
+ @Test
+ public void shouldParseCommentTest() {
+ assertThat(parser.parseCommentTest(tokenize("comment()")), is(notNullValue()));
+ }
+
+ @Test
+ public void shouldReturnNullFromParseCommentTestIfNotFollowedByOpenAndCloseParenthesis() {
+ assertThat(parser.parseCommentTest(tokenize("comment x )")), is(nullValue()));
+ assertThat(parser.parseCommentTest(tokenize("comment(x )")), is(nullValue()));
+ assertThat(parser.parseCommentTest(tokenize("comment(x")), is(nullValue()));
+ }
+
+ // ----------------------------------------------------------------------------------------------------------------
+ // text
+ // ----------------------------------------------------------------------------------------------------------------
+
+ @Test
+ public void shouldParseTextTest() {
+ assertThat(parser.parseTextTest(tokenize("text()")), is(notNullValue()));
+ }
+
+ @Test
+ public void shouldReturnNullFromParseTextTestIfNotFollowedByOpenAndCloseParenthesis() {
+ assertThat(parser.parseTextTest(tokenize("text x )")), is(nullValue()));
+ assertThat(parser.parseTextTest(tokenize("text(x )")), is(nullValue()));
+ assertThat(parser.parseTextTest(tokenize("text(x")), is(nullValue()));
+ }
+
+ // ----------------------------------------------------------------------------------------------------------------
+ // document-node
+ // ----------------------------------------------------------------------------------------------------------------
+
+ @Test
+ public void shouldParseDocumentTest() {
+ DocumentTest result = parser.parseDocumentTest(tokenize("document-node(element(foo:bar))"));
+ assertThat(result, is(notNullValue()));
+ assertThat(result.getElementTest().getElementName(), is(nameTest("foo", "bar")));
+ assertThat(result.getElementTest().getTypeName(), is(wildcard()));
+ assertThat(result.getSchemaElementTest(), is(nullValue()));
+
+ result = parser.parseDocumentTest(tokenize("document-node(schema-element(foo))"));
+ assertThat(result, is(notNullValue()));
+ assertThat(result.getSchemaElementTest().getElementDeclarationName(), is(nameTest("foo")));
+ assertThat(result.getElementTest(), is(nullValue()));
+ }
+
+ @Test
+ public void shouldReturnNullFromParseDocumentTestIfOpenParenthesisIsNotIncluded() {
+ assertThat(parser.parseDocumentTest(tokenize("document-node foo")), is(nullValue()));
+ assertThat(parser.parseDocumentTest(tokenize("document-node foo")), is(nullValue()));
+ }
+
+ @Test( expected = ParsingException.class )
+ public void shouldFailToParseDocumentTestIfDocumentNodeDoesNotContainElementOrSchemaElement() {
+ parser.parseDocumentTest(tokenize("document-node(foo)"));
+ }
+
+ // ----------------------------------------------------------------------------------------------------------------
+ // element
+ // ----------------------------------------------------------------------------------------------------------------
+
+ @Test
+ public void shouldParseElementTest() {
+ ElementTest result = parser.parseElementTest(tokenize("element(foo)"));
+ assertThat(result, is(notNullValue()));
+ assertThat(result.getElementName(), is(nameTest("foo")));
+ assertThat(result.getTypeName(), is(wildcard()));
+
+ result = parser.parseElementTest(tokenize("element(foo:bar)"));
+ assertThat(result, is(notNullValue()));
+ assertThat(result.getElementName(), is(nameTest("foo", "bar")));
+ assertThat(result.getTypeName(), is(wildcard()));
+
+ result = parser.parseElementTest(tokenize("element(foo:bar,baz)"));
+ assertThat(result, is(notNullValue()));
+ assertThat(result.getElementName(), is(nameTest("foo", "bar")));
+ assertThat(result.getTypeName(), is(nameTest("baz")));
+
+ result = parser.parseElementTest(tokenize("element(foo:bar,baz:bam)"));
+ assertThat(result, is(notNullValue()));
+ assertThat(result.getElementName(), is(nameTest("foo", "bar")));
+ assertThat(result.getTypeName(), is(nameTest("baz", "bam")));
+
+ result = parser.parseElementTest(tokenize("element(foo:bar,*)"));
+ assertThat(result, is(notNullValue()));
+ assertThat(result.getElementName(), is(nameTest("foo", "bar")));
+ assertThat(result.getTypeName(), is(wildcard()));
+
+ result = parser.parseElementTest(tokenize("element(*,foo:bar)"));
+ assertThat(result, is(notNullValue()));
+ assertThat(result.getElementName(), is(wildcard()));
+ assertThat(result.getTypeName(), is(nameTest("foo", "bar")));
+
+ result = parser.parseElementTest(tokenize("element(*,*)"));
+ assertThat(result, is(notNullValue()));
+ assertThat(result.getElementName(), is(wildcard()));
+ assertThat(result.getTypeName(), is(wildcard()));
+ }
+
+ @Test
+ public void shouldReturnNullFromParseElementTestIfOpenParenthesisIsNotIncluded() {
+ ElementTest result = parser.parseElementTest(tokenize("attribute foo"));
+ assertThat(result, is(nullValue()));
+ }
+
+ // ----------------------------------------------------------------------------------------------------------------
+ // schema-element
+ // ----------------------------------------------------------------------------------------------------------------
+
+ @Test
+ public void shouldParseSchemaElementTest() {
+ SchemaElementTest result = parser.parseSchemaElementTest(tokenize("schema-element(foo)"));
+ assertThat(result, is(notNullValue()));
+ assertThat(result.getElementDeclarationName(), is(nameTest("foo")));
+
+ result = parser.parseSchemaElementTest(tokenize("schema-element(foo:bar)"));
+ assertThat(result, is(notNullValue()));
+ assertThat(result.getElementDeclarationName(), is(nameTest("foo", "bar")));
+
+ result = parser.parseSchemaElementTest(tokenize("schema-element(*)"));
+ assertThat(result, is(notNullValue()));
+ assertThat(result.getElementDeclarationName(), is(wildcard()));
+ }
+
+ @Test
+ public void shouldReturnNullFromParseSchemaElementTestIfOpenParenthesisIsNotIncluded() {
+ SchemaElementTest result = parser.parseSchemaElementTest(tokenize("schema-element foo"));
+ assertThat(result, is(nullValue()));
+ }
+
+ // ----------------------------------------------------------------------------------------------------------------
+ // attribute
+ // ----------------------------------------------------------------------------------------------------------------
+
+ @Test
+ public void shouldParseAttributeTest() {
+ AttributeTest result = parser.parseAttributeTest(tokenize("attribute(foo)"));
+ assertThat(result, is(notNullValue()));
+ assertThat(result.getAttributeName(), is(nameTest("foo")));
+ assertThat(result.getTypeName(), is(wildcard()));
+
+ result = parser.parseAttributeTest(tokenize("attribute(foo:bar)"));
+ assertThat(result, is(notNullValue()));
+ assertThat(result.getAttributeName(), is(nameTest("foo", "bar")));
+ assertThat(result.getTypeName(), is(wildcard()));
+
+ result = parser.parseAttributeTest(tokenize("attribute(foo:bar,baz)"));
+ assertThat(result, is(notNullValue()));
+ assertThat(result.getAttributeName(), is(nameTest("foo", "bar")));
+ assertThat(result.getTypeName(), is(nameTest("baz")));
+
+ result = parser.parseAttributeTest(tokenize("attribute(foo:bar,baz:bar)"));
+ assertThat(result, is(notNullValue()));
+ assertThat(result.getAttributeName(), is(nameTest("foo", "bar")));
+ assertThat(result.getTypeName(), is(nameTest("baz", "bar")));
+
+ result = parser.parseAttributeTest(tokenize("attribute(*,baz:bar)"));
+ assertThat(result, is(notNullValue()));
+ assertThat(result.getAttributeName(), is(wildcard()));
+ assertThat(result.getTypeName(), is(nameTest("baz", "bar")));
+
+ result = parser.parseAttributeTest(tokenize("attribute(foo:bar,*)"));
+ assertThat(result, is(notNullValue()));
+ assertThat(result.getAttributeName(), is(nameTest("foo", "bar")));
+ assertThat(result.getTypeName(), is(wildcard()));
+ }
+
+ @Test
+ public void shouldReturnNullFromParseAttributeTestIfOpenParenthesisIsNotIncluded() {
+ AttributeTest result = parser.parseAttributeTest(tokenize("attribute foo"));
+ assertThat(result, is(nullValue()));
+ }
+
+ // ----------------------------------------------------------------------------------------------------------------
+ // schema-attribute
+ // ----------------------------------------------------------------------------------------------------------------
+
+ @Test
+ public void shouldParseSchemaAttributeTest() {
+ SchemaAttributeTest result = parser.parseSchemaAttributeTest(tokenize("schema-attribute(foo)"));
+ assertThat(result, is(notNullValue()));
+ assertThat(result.getAttributeDeclarationName(), is(nameTest("foo")));
+
+ result = parser.parseSchemaAttributeTest(tokenize("schema-attribute(foo:bar)"));
+ assertThat(result, is(notNullValue()));
+ assertThat(result.getAttributeDeclarationName(), is(nameTest("foo", "bar")));
+
+ result = parser.parseSchemaAttributeTest(tokenize("schema-attribute(*)"));
+ assertThat(result, is(notNullValue()));
+ assertThat(result.getAttributeDeclarationName(), is(wildcard()));
+ }
+
+ @Test
+ public void shouldReturnNullFromParseSchemaAttributeTestIfOpenParenthesisIsNotIncluded() {
+ SchemaAttributeTest result = parser.parseSchemaAttributeTest(tokenize("schema-attribute foo"));
+ assertThat(result, is(nullValue()));
+ }
+
+ protected TokenStream tokenize( String xpath ) {
+ Tokenizer tokenizer = new XPathTokenizer(false); // skip comments
+ return new TokenStream(xpath, tokenizer, true).start(); // case sensitive!!
+ }
+
+ protected DescendantOrSelf descendantOrSelf() {
+ return new DescendantOrSelf();
+ }
+
+ protected AxisStep axisStep( NodeTest nodeTest,
+ Component... predicates ) {
+ return new AxisStep(nodeTest, predicates(predicates));
+ }
+
+ protected FilterStep filterStep( Component primaryExpression,
+ Component... predicates ) {
+ return new FilterStep(primaryExpression, predicates(predicates));
+ }
+
+ protected PathExpression pathExpr( StepExpression... steps ) {
+ return pathExpr(Arrays.asList(steps));
+ }
+
+ protected PathExpression pathExpr( List<StepExpression> steps ) {
+ return new PathExpression(false, steps);
+ }
+
+ protected PathExpression relativePathExpr( StepExpression... steps ) {
+ return relativePathExpr(Arrays.asList(steps));
+ }
+
+ protected PathExpression relativePathExpr( List<StepExpression> steps ) {
+ return new PathExpression(true, steps);
+ }
+
+ protected Literal literal( String value ) {
+ return new Literal(value);
+ }
+
+ protected ContextItem contextItem() {
+ return new ContextItem();
+ }
+
+ protected List<Component> predicates( Component... predicates ) {
+ return Arrays.asList(predicates);
+ }
+
+ protected ParenthesizedExpression paren( Component value ) {
+ return new ParenthesizedExpression(value);
+ }
+
+ protected AttributeNameTest attributeNameTest( NameTest nameTest ) {
+ return new AttributeNameTest(nameTest);
+ }
+
+ protected AttributeTest attribute( NameTest name ) {
+ return new AttributeTest(name, null);
+ }
+
+ protected AttributeTest attribute( NameTest name,
+ NameTest type ) {
+ return new AttributeTest(name, type);
+ }
+
+ protected FunctionCall functionCall( NameTest name,
+ Component... parameters ) {
+ return new FunctionCall(name, Arrays.asList(parameters));
+ }
+
+ protected NameTest wildcard() {
+ return new NameTest(null, null);
+ }
+
+ protected NameTest nameTest( String localPart ) {
+ return new NameTest(null, localPart);
+ }
+
+ protected NameTest nameTest( String prefix,
+ String local ) {
+ return new NameTest(prefix, local);
+ }
+
+ protected void assertParsable( String xpath ) {
+ new XPathParser().parseQuery(xpath, context);
+ }
+
+ protected void assertNotParsable( String xpath ) {
+ try {
+ new XPathParser().parseQuery(xpath, context);
+ fail("Expected an invalid XPath: " + xpath);
+ } catch (ParsingException e) {
+ // expected
+ }
+ }
+
+}
Property changes on: trunk/dna-jcr/src/test/java/org/jboss/dna/jcr/xpath/XPathParserTest.java
___________________________________________________________________
Name: svn:keywords
+ Id Revision
Name: svn:eol-style
+ LF
16 years, 7 months
DNA SVN: r1282 - in trunk/web/dna-web-jcr-rest-client/src/main: java/org/jboss/dna/web/jcr/rest/client/http and 2 other directories.
by dna-commits@lists.jboss.org
Author: elvisisking
Date: 2009-10-02 13:05:21 -0400 (Fri, 02 Oct 2009)
New Revision: 1282
Removed:
trunk/web/dna-web-jcr-rest-client/src/main/java/org/jboss/dna/web/jcr/rest/client/ServerAuthenticator.java
trunk/web/dna-web-jcr-rest-client/src/main/java/org/jboss/dna/web/jcr/rest/client/http/HttpUrlConnection.java
trunk/web/dna-web-jcr-rest-client/src/main/java/org/jboss/dna/web/jcr/rest/client/http/IHttpConnection.java
Modified:
trunk/web/dna-web-jcr-rest-client/src/main/java/org/jboss/dna/web/jcr/rest/client/RestClientI18n.java
trunk/web/dna-web-jcr-rest-client/src/main/java/org/jboss/dna/web/jcr/rest/client/ServerManager.java
trunk/web/dna-web-jcr-rest-client/src/main/java/org/jboss/dna/web/jcr/rest/client/http/HttpClientConnection.java
trunk/web/dna-web-jcr-rest-client/src/main/java/org/jboss/dna/web/jcr/rest/client/json/JsonRestClient.java
trunk/web/dna-web-jcr-rest-client/src/main/resources/org/jboss/dna/web/jcr/rest/client/RestClientI18n.properties
Log:
DNA 532 Delete IHttpConnection Interface Since There Is Only One Implementation That Works Correctly: Deleted IHttpConnection and HttpUrlConnection. Since the Apache HttpClient implementation is the only one that works properly no need to keep the java.net implementation or the interface around.
Modified: trunk/web/dna-web-jcr-rest-client/src/main/java/org/jboss/dna/web/jcr/rest/client/RestClientI18n.java
===================================================================
--- trunk/web/dna-web-jcr-rest-client/src/main/java/org/jboss/dna/web/jcr/rest/client/RestClientI18n.java 2009-10-02 17:03:04 UTC (rev 1281)
+++ trunk/web/dna-web-jcr-rest-client/src/main/java/org/jboss/dna/web/jcr/rest/client/RestClientI18n.java 2009-10-02 17:05:21 UTC (rev 1282)
@@ -71,6 +71,8 @@
public static I18n serverManagerUnregisteredServer;
public static I18n serverShortDescription;
+
+ public static I18n unknownHttpRequestMethodMsg;
public static I18n workspaceEmptyNameMsg;
Deleted: trunk/web/dna-web-jcr-rest-client/src/main/java/org/jboss/dna/web/jcr/rest/client/ServerAuthenticator.java
===================================================================
--- trunk/web/dna-web-jcr-rest-client/src/main/java/org/jboss/dna/web/jcr/rest/client/ServerAuthenticator.java 2009-10-02 17:03:04 UTC (rev 1281)
+++ trunk/web/dna-web-jcr-rest-client/src/main/java/org/jboss/dna/web/jcr/rest/client/ServerAuthenticator.java 2009-10-02 17:05:21 UTC (rev 1282)
@@ -1,51 +0,0 @@
-/*
- * JBoss DNA (http://www.jboss.org/dna)
- * 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.
- * See the AUTHORS.txt file in the distribution for a full listing of
- * individual contributors.
- *
- * JBoss DNA is free software. Unless otherwise indicated, all code in JBoss DNA
- * is licensed to you 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.
- *
- * JBoss DNA 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 software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- */
-package org.jboss.dna.web.jcr.rest.client;
-
-import java.net.Authenticator;
-import java.net.PasswordAuthentication;
-import org.jboss.dna.web.jcr.rest.client.domain.Server;
-
-/**
- * The <code>ServerAuthenticator</code> class provides user names and passwords to the HTTP connection.
- */
-public class ServerAuthenticator extends Authenticator {
-
- // ===========================================================================================================================
- // Methods
- // ===========================================================================================================================
-
- /**
- * {@inheritDoc}
- *
- * @see java.net.Authenticator#getPasswordAuthentication()
- */
- @Override
- protected PasswordAuthentication getPasswordAuthentication() {
- Server server = ServerManager.getCurrentServer();
- String password = ((server.getPassword() == null) ? "" : server.getPassword()); //$NON-NLS-1$
- return new PasswordAuthentication(server.getUser(), password.toCharArray());
- }
-
-}
Modified: trunk/web/dna-web-jcr-rest-client/src/main/java/org/jboss/dna/web/jcr/rest/client/ServerManager.java
===================================================================
--- trunk/web/dna-web-jcr-rest-client/src/main/java/org/jboss/dna/web/jcr/rest/client/ServerManager.java 2009-10-02 17:03:04 UTC (rev 1281)
+++ trunk/web/dna-web-jcr-rest-client/src/main/java/org/jboss/dna/web/jcr/rest/client/ServerManager.java 2009-10-02 17:05:21 UTC (rev 1282)
@@ -98,29 +98,6 @@
private static final String USER_TAG = "user"; //$NON-NLS-1$
// ===========================================================================================================================
- // Class Fields
- // ===========================================================================================================================
-
- /**
- * The java.net.Authenticator needs server information to complete the publish, unpublish, getRepositories(), and
- * getWorkspaces() operations. Setting a thread variable was a way to do that.
- *
- * @see ServerAuthenticator
- */
- private static ThreadLocal<Server> currentServer = new ThreadLocal<Server>();
-
- // ===========================================================================================================================
- // Class Methods
- // ===========================================================================================================================
-
- /**
- * @return the server set on the current thread or <code>null</code>
- */
- public static Server getCurrentServer() {
- return ServerManager.currentServer.get();
- }
-
- // ===========================================================================================================================
// Fields
// ===========================================================================================================================
@@ -275,7 +252,6 @@
this.serverLock.readLock().lock();
if (isRegistered(server)) {
- ServerManager.currentServer.set(server);
Collection<Repository> repositories = this.delegate.getRepositories(server);
return Collections.unmodifiableCollection(new ArrayList<Repository>(repositories));
}
@@ -313,7 +289,6 @@
this.serverLock.readLock().lock();
if (isRegistered(repository.getServer())) {
- ServerManager.currentServer.set(repository.getServer());
Collection<Workspace> workspaces = this.delegate.getWorkspaces(repository);
return Collections.unmodifiableCollection(new ArrayList<Workspace>(workspaces));
}
@@ -482,11 +457,10 @@
CheckArg.isNotNull(server, "server"); //$NON-NLS-1$
try {
- ServerManager.currentServer.set(server);
this.delegate.getRepositories(server);
return new Status(Severity.OK, RestClientI18n.serverManagerConnectionEstablishedMsg.text(), null);
} catch (Exception e) {
- return new Status(Severity.ERROR, RestClientI18n.serverManagerConnectionFailedMsg.text(), null);
+ return new Status(Severity.ERROR, RestClientI18n.serverManagerConnectionFailedMsg.text(e), null);
}
}
@@ -509,7 +483,6 @@
Server server = workspace.getServer();
if (isRegistered(server)) {
- ServerManager.currentServer.set(server);
return this.delegate.publish(workspace, path, file);
}
@@ -652,7 +625,6 @@
Server server = workspace.getServer();
if (isRegistered(server)) {
- ServerManager.currentServer.set(server);
return this.delegate.unpublish(workspace, path, file);
}
Modified: trunk/web/dna-web-jcr-rest-client/src/main/java/org/jboss/dna/web/jcr/rest/client/http/HttpClientConnection.java
===================================================================
--- trunk/web/dna-web-jcr-rest-client/src/main/java/org/jboss/dna/web/jcr/rest/client/http/HttpClientConnection.java 2009-10-02 17:03:04 UTC (rev 1281)
+++ trunk/web/dna-web-jcr-rest-client/src/main/java/org/jboss/dna/web/jcr/rest/client/http/HttpClientConnection.java 2009-10-02 17:05:21 UTC (rev 1282)
@@ -23,6 +23,7 @@
*/
package org.jboss.dna.web.jcr.rest.client.http;
+import static org.jboss.dna.web.jcr.rest.client.RestClientI18n.unknownHttpRequestMethodMsg;
import java.net.URL;
import javax.ws.rs.core.MediaType;
import org.apache.http.HttpResponse;
@@ -38,13 +39,14 @@
import org.apache.http.impl.client.AbstractHttpClient;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.util.EntityUtils;
+import org.jboss.dna.common.util.CheckArg;
import org.jboss.dna.web.jcr.rest.client.domain.Server;
import org.jboss.dna.web.jcr.rest.client.json.IJsonConstants.RequestMethod;
/**
- * <code>HttpClientConnection</code> is an <code>Apache HttpClient</code> implementation of <code>IHttpConnection</code>.
+ * <code>HttpClientConnection</code> uses the <code>Apache HttpClient</code>.
*/
-public final class HttpClientConnection implements IHttpConnection {
+public final class HttpClientConnection {
// ===========================================================================================================================
// Fields
@@ -70,14 +72,18 @@
// ===========================================================================================================================
/**
- * @param server the server with the host and port information
- * @param url the URL that will be used in the request
- * @param method the HTTP request method
+ * @param server the server with the host and port information (never <code>null</code>)
+ * @param url the URL that will be used in the request (never <code>null</code>)
+ * @param method the HTTP request method (never <code>null</code>)
* @throws Exception if there is a problem establishing the connection
*/
public HttpClientConnection( Server server,
URL url,
RequestMethod method ) throws Exception {
+ CheckArg.isNotNull(server, "server"); //$NON-NLS-1$
+ CheckArg.isNotNull(url, "url"); //$NON-NLS-1$
+ CheckArg.isNotNull(method, "method"); //$NON-NLS-1$
+
this.httpClient = new DefaultHttpClient();
this.httpClient.getCredentialsProvider().setCredentials(new AuthScope(url.getHost(), url.getPort()),
new UsernamePasswordCredentials(server.getUser(),
@@ -92,8 +98,7 @@
} else if (RequestMethod.PUT == method) {
this.request = new HttpPut();
} else {
- // TODO need exception message
- throw new RuntimeException();
+ throw new RuntimeException(unknownHttpRequestMethodMsg.text(method));
}
// set request URI
@@ -105,9 +110,7 @@
// ===========================================================================================================================
/**
- * {@inheritDoc}
- *
- * @see org.jboss.dna.web.jcr.rest.client.http.IHttpConnection#disconnect()
+ * Disconnects this connection.
*/
public void disconnect() {
this.httpClient.getConnectionManager().shutdown();
@@ -126,29 +129,28 @@
}
/**
- * {@inheritDoc}
- *
- * @see org.jboss.dna.web.jcr.rest.client.http.IHttpConnection#getResponseCode()
+ * @return the HTTP response code
+ * @throws Exception if there is a problem getting the response code
*/
public int getResponseCode() throws Exception {
return getResponse().getStatusLine().getStatusCode();
}
/**
- * {@inheritDoc}
- *
- * @see org.jboss.dna.web.jcr.rest.client.http.IHttpConnection#read()
+ * @return the HTTP response body as a string
+ * @throws Exception if there is a problem reading from the connection
*/
public String read() throws Exception {
return EntityUtils.toString(getResponse().getEntity());
}
/**
- * {@inheritDoc}
- *
- * @see org.jboss.dna.web.jcr.rest.client.http.IHttpConnection#write(byte[])
+ * @param bytes the bytes being posted to the HTTP connection (never <code>null</code>)
+ * @throws Exception if there is a problem writing to the connection
*/
public void write( byte[] bytes ) throws Exception {
+ CheckArg.isNotNull(bytes, "bytes"); //$NON-NLS-1$
+
ByteArrayEntity entity = new ByteArrayEntity(bytes);
entity.setContentType(MediaType.APPLICATION_JSON);
Deleted: trunk/web/dna-web-jcr-rest-client/src/main/java/org/jboss/dna/web/jcr/rest/client/http/HttpUrlConnection.java
===================================================================
--- trunk/web/dna-web-jcr-rest-client/src/main/java/org/jboss/dna/web/jcr/rest/client/http/HttpUrlConnection.java 2009-10-02 17:03:04 UTC (rev 1281)
+++ trunk/web/dna-web-jcr-rest-client/src/main/java/org/jboss/dna/web/jcr/rest/client/http/HttpUrlConnection.java 2009-10-02 17:05:21 UTC (rev 1282)
@@ -1,124 +0,0 @@
-/*
- * JBoss DNA (http://www.jboss.org/dna)
- * 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.
- * See the AUTHORS.txt file in the distribution for a full listing of
- * individual contributors.
- *
- * JBoss DNA is free software. Unless otherwise indicated, all code in JBoss DNA
- * is licensed to you 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.
- *
- * JBoss DNA 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 software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- */
-package org.jboss.dna.web.jcr.rest.client.http;
-
-import java.net.Authenticator;
-import java.net.HttpURLConnection;
-import java.net.URL;
-import javax.ws.rs.core.MediaType;
-import org.jboss.dna.common.util.Base64;
-import org.jboss.dna.web.jcr.rest.client.ServerAuthenticator;
-import org.jboss.dna.web.jcr.rest.client.domain.Server;
-import org.jboss.dna.web.jcr.rest.client.json.JsonUtils;
-import org.jboss.dna.web.jcr.rest.client.json.IJsonConstants.RequestMethod;
-
-/**
- * <code>HttpUrlConnection</code> is a <code>java.net</code> implementation of <code>IHttpConnection</code>.
- */
-public final class HttpUrlConnection implements IHttpConnection {
-
- // ===========================================================================================================================
- // Class Initializer
- // ===========================================================================================================================
-
- static {
- // must be set when using java.net framework but a problem occurs when other subsytems have their own Authenticator and
- // also call this method
- Authenticator.setDefault(new ServerAuthenticator());
- }
-
- // ===========================================================================================================================
- // Fields
- // ===========================================================================================================================
-
- /**
- * The HTTP connection that executes the request and obtains the response.
- */
- private final HttpURLConnection connection;
-
- // ===========================================================================================================================
- // Constructors
- // ===========================================================================================================================
-
- /**
- * @param server the server with the host and port information
- * @param url the URL that will be used in the request
- * @param method the HTTP request method
- * @throws Exception if there is a problem establishing the connection
- */
- public HttpUrlConnection( Server server,
- URL url,
- RequestMethod method ) throws Exception {
- this.connection = (HttpURLConnection)url.openConnection();
- this.connection.setDoOutput(true);
-
- String encoding = Base64.encodeBytes((server.getUser() + ':' + server.getPassword()).getBytes());
- this.connection.setRequestProperty("Authorization", "Basic " + encoding); //$NON-NLS-1$ //$NON-NLS-2$
-
- this.connection.setRequestMethod(method.toString());
- this.connection.setRequestProperty("Content-Type", MediaType.APPLICATION_JSON); //$NON-NLS-1$
- this.connection.setUseCaches(false);
- }
-
- // ===========================================================================================================================
- // Methods
- // ===========================================================================================================================
-
- /**
- * {@inheritDoc}
- *
- * @see org.jboss.dna.web.jcr.rest.client.http.IHttpConnection#disconnect()
- */
- public void disconnect() {
- this.connection.disconnect();
- }
-
- /**
- * {@inheritDoc}
- *
- * @see org.jboss.dna.web.jcr.rest.client.http.IHttpConnection#getResponseCode()
- */
- public int getResponseCode() throws Exception {
- return this.connection.getResponseCode();
- }
-
- /**
- * {@inheritDoc}
- *
- * @see org.jboss.dna.web.jcr.rest.client.http.IHttpConnection#read()
- */
- public String read() throws Exception {
- return JsonUtils.readInputStream(this.connection);
- }
-
- /**
- * {@inheritDoc}
- *
- * @see org.jboss.dna.web.jcr.rest.client.http.IHttpConnection#write(byte[])
- */
- public void write( byte[] bytes ) throws Exception {
- connection.getOutputStream().write(bytes);
- }
-
-}
Deleted: trunk/web/dna-web-jcr-rest-client/src/main/java/org/jboss/dna/web/jcr/rest/client/http/IHttpConnection.java
===================================================================
--- trunk/web/dna-web-jcr-rest-client/src/main/java/org/jboss/dna/web/jcr/rest/client/http/IHttpConnection.java 2009-10-02 17:03:04 UTC (rev 1281)
+++ trunk/web/dna-web-jcr-rest-client/src/main/java/org/jboss/dna/web/jcr/rest/client/http/IHttpConnection.java 2009-10-02 17:05:21 UTC (rev 1282)
@@ -1,55 +0,0 @@
-/*
- * JBoss DNA (http://www.jboss.org/dna)
- * 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.
- * See the AUTHORS.txt file in the distribution for a full listing of
- * individual contributors.
- *
- * JBoss DNA is free software. Unless otherwise indicated, all code in JBoss DNA
- * is licensed to you 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.
- *
- * JBoss DNA 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 software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- */
-package org.jboss.dna.web.jcr.rest.client.http;
-
-/**
- * The <code>IHttpConnection</code> is the contract for all HTTP connection frameworks must implement to work with the DNA REST
- * server.
- */
-public interface IHttpConnection {
-
- /**
- * Disconnects this connection.
- */
- void disconnect();
-
- /**
- * @return the HTTP response code
- * @throws Exception if there is a problem getting the response code
- */
- int getResponseCode() throws Exception;
-
- /**
- * @return the HTTP response body as a string
- * @throws Exception if there is a problem reading from the connection
- */
- String read() throws Exception;
-
- /**
- * @param bytes the bytes being posted to the HTTP connection
- * @throws Exception if there is a problem writing to the connection
- */
- void write( byte[] bytes ) throws Exception;
-
-}
Modified: trunk/web/dna-web-jcr-rest-client/src/main/java/org/jboss/dna/web/jcr/rest/client/json/JsonRestClient.java
===================================================================
--- trunk/web/dna-web-jcr-rest-client/src/main/java/org/jboss/dna/web/jcr/rest/client/json/JsonRestClient.java 2009-10-02 17:03:04 UTC (rev 1281)
+++ trunk/web/dna-web-jcr-rest-client/src/main/java/org/jboss/dna/web/jcr/rest/client/json/JsonRestClient.java 2009-10-02 17:05:21 UTC (rev 1282)
@@ -37,7 +37,6 @@
import org.jboss.dna.web.jcr.rest.client.domain.Server;
import org.jboss.dna.web.jcr.rest.client.domain.Workspace;
import org.jboss.dna.web.jcr.rest.client.http.HttpClientConnection;
-import org.jboss.dna.web.jcr.rest.client.http.IHttpConnection;
import org.jboss.dna.web.jcr.rest.client.json.IJsonConstants.RequestMethod;
/**
@@ -66,11 +65,10 @@
* @return the connection which <strong>MUST</strong> be disconnected
* @throws Exception if there is a problem establishing the connection
*/
- private IHttpConnection connect( Server server,
- URL url,
- RequestMethod method ) throws Exception {
+ private HttpClientConnection connect( Server server,
+ URL url,
+ RequestMethod method ) throws Exception {
this.logger.trace("connect: url={0}, method={1}", url, method); //$NON-NLS-1$
- // return new HttpUrlConnection(server, url, method);
return new HttpClientConnection(server, url, method);
}
@@ -87,7 +85,7 @@
File file ) throws Exception {
this.logger.trace("createFileNode: workspace={0}, path={1}, file={2}", workspace.getName(), path, file.getAbsolutePath()); //$NON-NLS-1$
FileNode fileNode = new FileNode(workspace, path, file);
- IHttpConnection connection = connect(workspace.getServer(), fileNode.getUrl(), RequestMethod.POST);
+ HttpClientConnection connection = connect(workspace.getServer(), fileNode.getUrl(), RequestMethod.POST);
try {
this.logger.trace("createFileNode: create node={0}", fileNode); //$NON-NLS-1$
@@ -122,7 +120,7 @@
String path ) throws Exception {
this.logger.trace("createFolderNode: workspace={0}, path={1}", workspace.getName(), path); //$NON-NLS-1$
FolderNode folderNode = new FolderNode(workspace, path);
- IHttpConnection connection = connect(workspace.getServer(), folderNode.getUrl(), RequestMethod.POST);
+ HttpClientConnection connection = connect(workspace.getServer(), folderNode.getUrl(), RequestMethod.POST);
try {
this.logger.trace("createFolderNode: create node={0}", folderNode); //$NON-NLS-1$
@@ -194,7 +192,7 @@
this.logger.trace("getRepositories: server={0}", server); //$NON-NLS-1$
ServerNode serverNode = new ServerNode(server);
- IHttpConnection connection = connect(server, serverNode.getFindRepositoriesUrl(), RequestMethod.GET);
+ HttpClientConnection connection = connect(server, serverNode.getFindRepositoriesUrl(), RequestMethod.GET);
try {
if (connection.getResponseCode() == HttpURLConnection.HTTP_OK) {
@@ -244,7 +242,7 @@
this.logger.trace("getWorkspaces: repository={0}", repository); //$NON-NLS-1$
RepositoryNode repositoryNode = new RepositoryNode(repository);
- IHttpConnection connection = connect(repository.getServer(), repositoryNode.getUrl(), RequestMethod.GET);
+ HttpClientConnection connection = connect(repository.getServer(), repositoryNode.getUrl(), RequestMethod.GET);
try {
if (connection.getResponseCode() == HttpURLConnection.HTTP_OK) {
@@ -278,7 +276,7 @@
String path,
File file ) throws Exception {
FileNode fileNode = new FileNode(workspace, path, file);
- IHttpConnection connection = connect(workspace.getServer(), fileNode.getFileContentsUrl(), RequestMethod.GET);
+ HttpClientConnection connection = connect(workspace.getServer(), fileNode.getFileContentsUrl(), RequestMethod.GET);
int responseCode = connection.getResponseCode();
if (responseCode == HttpURLConnection.HTTP_OK) {
@@ -298,7 +296,7 @@
private boolean pathExists( Server server,
URL url ) throws Exception {
this.logger.trace("pathExists: url={0}", url); //$NON-NLS-1$
- IHttpConnection connection = connect(server, url, RequestMethod.GET);
+ HttpClientConnection connection = connect(server, url, RequestMethod.GET);
try {
int responseCode = connection.getResponseCode();
@@ -373,7 +371,7 @@
CheckArg.isNotNull(file, "file"); //$NON-NLS-1$
this.logger.trace("unpublish: workspace={0}, path={1}, file={2}", workspace.getName(), path, file.getAbsolutePath()); //$NON-NLS-1$
- IHttpConnection connection = null;
+ HttpClientConnection connection = null;
try {
FileNode fileNode = new FileNode(workspace, path, file);
Modified: trunk/web/dna-web-jcr-rest-client/src/main/resources/org/jboss/dna/web/jcr/rest/client/RestClientI18n.properties
===================================================================
--- trunk/web/dna-web-jcr-rest-client/src/main/resources/org/jboss/dna/web/jcr/rest/client/RestClientI18n.properties 2009-10-02 17:03:04 UTC (rev 1281)
+++ trunk/web/dna-web-jcr-rest-client/src/main/resources/org/jboss/dna/web/jcr/rest/client/RestClientI18n.properties 2009-10-02 17:05:21 UTC (rev 1282)
@@ -38,7 +38,7 @@
serverShortDescription = DNA Server - URL: {0} User: {1}
serverManagerConnectionEstablishedMsg = Connection established.
-serverManagerConnectionFailedMsg = Connection failed.
+serverManagerConnectionFailedMsg = Connection failed. Error Message: {0}
serverManagerRegistryAddUnexpectedError = Unexpected error adding server to registry
serverManagerRegistryListenerError = This error was reported by an IServerRegistryListener
serverManagerRegistryListenerErrorsOccurred = Errors occurred processing a server registry event. Check error log for more details.
@@ -47,6 +47,8 @@
serverManagerRegistryUpdateRemoveError = There was an unexpected error updating the server in the registry. The server has not been updated in the server registry. Detail: {0}
serverManagerUnregisteredServer = Server "{0}" is not registered so it's repositories and workspaces cannot be obtained and it cannot be involved in a publishing operation.
+unknownHttpRequestMethodMsg = The "{0}" HTTP request method is not valid.
+
workspaceEmptyNameMsg = A workspace name cannot be empty
workspaceNullRepositoryMsg = A workspace repository cannot be null
workspaceShortDescription = DNA Workspace - Name: {0}, Repository: {1}
16 years, 7 months
DNA SVN: r1281 - in trunk/tools/org.jboss.dna.eclipse.jcr.rest.client: src/org/jboss/dna/eclipse/jcr/rest/client and 1 other directories.
by dna-commits@lists.jboss.org
Author: elvisisking
Date: 2009-10-02 13:03:04 -0400 (Fri, 02 Oct 2009)
New Revision: 1281
Modified:
trunk/tools/org.jboss.dna.eclipse.jcr.rest.client/dna-web-jcr-rest-client-0.7-SNAPSHOT-jar-with-dependencies.jar
trunk/tools/org.jboss.dna.eclipse.jcr.rest.client/dna-web-jcr-rest-client-0.7-SNAPSHOT-sources.jar
trunk/tools/org.jboss.dna.eclipse.jcr.rest.client/src/org/jboss/dna/eclipse/jcr/rest/client/DnaResourceHelper.java
trunk/tools/org.jboss.dna.eclipse.jcr.rest.client/src/org/jboss/dna/eclipse/jcr/rest/client/views/ServerView.java
Log:
DNA 531 Servers View Should Provide Global Action Handlers: Setup no-op actions for cut, copy, and paste, and hooked up the delete server action to work with the delete key and the global delete action. Also added updated client jars from Maven project.
Modified: trunk/tools/org.jboss.dna.eclipse.jcr.rest.client/dna-web-jcr-rest-client-0.7-SNAPSHOT-jar-with-dependencies.jar
===================================================================
(Binary files differ)
Modified: trunk/tools/org.jboss.dna.eclipse.jcr.rest.client/dna-web-jcr-rest-client-0.7-SNAPSHOT-sources.jar
===================================================================
(Binary files differ)
Modified: trunk/tools/org.jboss.dna.eclipse.jcr.rest.client/src/org/jboss/dna/eclipse/jcr/rest/client/DnaResourceHelper.java
===================================================================
--- trunk/tools/org.jboss.dna.eclipse.jcr.rest.client/src/org/jboss/dna/eclipse/jcr/rest/client/DnaResourceHelper.java 2009-10-02 16:13:40 UTC (rev 1280)
+++ trunk/tools/org.jboss.dna.eclipse.jcr.rest.client/src/org/jboss/dna/eclipse/jcr/rest/client/DnaResourceHelper.java 2009-10-02 17:03:04 UTC (rev 1281)
@@ -63,7 +63,7 @@
* file has been published to at least one DNA repository. The value of the property is a list of DNA repository workspaces
* where this file has been published.
*/
- private static QualifiedName PUBLISHED_RESOURCE_PROPERTY = new QualifiedName(IUiConstants.PLUGIN_ID, "publishedIn"); //$NON-NLS-1$
+ private static QualifiedName PUBLISHED_RESOURCE_PROPERTY = new QualifiedName(IUiConstants.PLUGIN_ID, "publishedLocations"); //$NON-NLS-1$
// ===========================================================================================================================
// Fields
Modified: trunk/tools/org.jboss.dna.eclipse.jcr.rest.client/src/org/jboss/dna/eclipse/jcr/rest/client/views/ServerView.java
===================================================================
--- trunk/tools/org.jboss.dna.eclipse.jcr.rest.client/src/org/jboss/dna/eclipse/jcr/rest/client/views/ServerView.java 2009-10-02 16:13:40 UTC (rev 1280)
+++ trunk/tools/org.jboss.dna.eclipse.jcr.rest.client/src/org/jboss/dna/eclipse/jcr/rest/client/views/ServerView.java 2009-10-02 17:03:04 UTC (rev 1281)
@@ -39,9 +39,13 @@
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.KeyAdapter;
+import org.eclipse.swt.events.KeyEvent;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.swt.widgets.Shell;
+import org.eclipse.ui.IActionBars;
+import org.eclipse.ui.actions.ActionFactory;
import org.eclipse.ui.actions.BaseSelectionListenerAction;
import org.eclipse.ui.help.IWorkbenchHelpSystem;
import org.eclipse.ui.part.ViewPart;
@@ -208,6 +212,7 @@
constructActions();
constructToolBar();
constructContextMenu();
+ hookGlobalActions();
setTitleToolTip(RestClientI18n.serverViewToolTip.text());
@@ -230,6 +235,10 @@
super.dispose();
}
+ IAction getDeleteAction() {
+ return this.deleteAction;
+ }
+
/**
* @return the server manager being used by this view
*/
@@ -259,6 +268,36 @@
}
/**
+ * Sets global action handlers.
+ */
+ private void hookGlobalActions() {
+ IActionBars bars = getViewSite().getActionBars();
+
+ // hook delete server action up
+ bars.setGlobalActionHandler(ActionFactory.DELETE.getId(), this.deleteAction);
+ this.viewer.getControl().addKeyListener(new KeyAdapter() {
+ @Override
+ public void keyPressed( KeyEvent event ) {
+ if ((event.character == SWT.DEL) && (event.stateMask == 0) && getDeleteAction().isEnabled()) {
+ getDeleteAction().run();
+ }
+ }
+ });
+
+ // don't want cut, copy, or paste actions so hook them up with a disabled action
+ class NoOpAction extends Action {
+ NoOpAction() {
+ setEnabled(false);
+ }
+ }
+
+ IAction noop = new NoOpAction();
+ bars.setGlobalActionHandler(ActionFactory.CUT.getId(), noop);
+ bars.setGlobalActionHandler(ActionFactory.COPY.getId(), noop);
+ bars.setGlobalActionHandler(ActionFactory.PASTE.getId(), noop);
+ }
+
+ /**
* {@inheritDoc}
*
* @see org.jboss.dna.web.jcr.rest.client.IServerRegistryListener#serverRegistryChanged(org.jboss.dna.web.jcr.rest.client.ServerRegistryEvent)
16 years, 7 months
DNA SVN: r1280 - in branches/ddl_sequencer: extensions and 42 other directories.
by dna-commits@lists.jboss.org
Author: blafond
Date: 2009-10-02 12:13:40 -0400 (Fri, 02 Oct 2009)
New Revision: 1280
Added:
branches/ddl_sequencer/.project
branches/ddl_sequencer/extensions/dna-sequencer-ddl/
branches/ddl_sequencer/extensions/dna-sequencer-ddl/.classpath
branches/ddl_sequencer/extensions/dna-sequencer-ddl/.project
branches/ddl_sequencer/extensions/dna-sequencer-ddl/.settings/
branches/ddl_sequencer/extensions/dna-sequencer-ddl/pom.xml
branches/ddl_sequencer/extensions/dna-sequencer-ddl/src/
branches/ddl_sequencer/extensions/dna-sequencer-ddl/src/main/
branches/ddl_sequencer/extensions/dna-sequencer-ddl/src/main/java/
branches/ddl_sequencer/extensions/dna-sequencer-ddl/src/main/java/org/
branches/ddl_sequencer/extensions/dna-sequencer-ddl/src/main/java/org/jboss/
branches/ddl_sequencer/extensions/dna-sequencer-ddl/src/main/java/org/jboss/dna/
branches/ddl_sequencer/extensions/dna-sequencer-ddl/src/main/java/org/jboss/dna/sequencer/
branches/ddl_sequencer/extensions/dna-sequencer-ddl/src/main/java/org/jboss/dna/sequencer/ddl/
branches/ddl_sequencer/extensions/dna-sequencer-ddl/src/main/java/org/jboss/dna/sequencer/ddl/datatype/
branches/ddl_sequencer/extensions/dna-sequencer-ddl/src/main/java/org/jboss/dna/sequencer/ddl/datatype/DataType.java
branches/ddl_sequencer/extensions/dna-sequencer-ddl/src/main/java/org/jboss/dna/sequencer/ddl/datatype/DataTypeParser.java
branches/ddl_sequencer/extensions/dna-sequencer-ddl/src/main/java/org/jboss/dna/sequencer/ddl/dialect/
branches/ddl_sequencer/extensions/dna-sequencer-ddl/src/main/java/org/jboss/dna/sequencer/ddl/dialect/Db2DdlParser.java
branches/ddl_sequencer/extensions/dna-sequencer-ddl/src/main/java/org/jboss/dna/sequencer/ddl/dialect/DerbyDdlParser.java
branches/ddl_sequencer/extensions/dna-sequencer-ddl/src/main/java/org/jboss/dna/sequencer/ddl/dialect/MySqlDdlParser.java
branches/ddl_sequencer/extensions/dna-sequencer-ddl/src/main/java/org/jboss/dna/sequencer/ddl/dialect/PostgresDdlParser.java
branches/ddl_sequencer/extensions/dna-sequencer-ddl/src/main/java/org/jboss/dna/sequencer/ddl/dialect/SqlServerDdlParser.java
branches/ddl_sequencer/extensions/dna-sequencer-ddl/src/main/java/org/jboss/dna/sequencer/ddl/dialect/SybaseDdlParser.java
branches/ddl_sequencer/extensions/dna-sequencer-ddl/src/main/java/org/jboss/dna/sequencer/ddl/dialect/derby/
branches/ddl_sequencer/extensions/dna-sequencer-ddl/src/main/java/org/jboss/dna/sequencer/ddl/dialect/derby/DerbyDdlConstants.java
branches/ddl_sequencer/extensions/dna-sequencer-ddl/src/main/java/org/jboss/dna/sequencer/ddl/dialect/oracle/
branches/ddl_sequencer/extensions/dna-sequencer-ddl/src/main/java/org/jboss/dna/sequencer/ddl/dialect/oracle/OracleDdlConstants.java
branches/ddl_sequencer/extensions/dna-sequencer-ddl/src/main/java/org/jboss/dna/sequencer/ddl/dialect/oracle/OracleDdlParser.java
branches/ddl_sequencer/extensions/dna-sequencer-ddl/src/main/java/org/jboss/dna/sequencer/ddl/statement/
branches/ddl_sequencer/extensions/dna-sequencer-ddl/src/main/java/org/jboss/dna/sequencer/ddl/statement/AlterTable.java
branches/ddl_sequencer/extensions/dna-sequencer-ddl/src/main/java/org/jboss/dna/sequencer/ddl/statement/Column.java
branches/ddl_sequencer/extensions/dna-sequencer-ddl/src/main/java/org/jboss/dna/sequencer/ddl/statement/ForeignKeyReference.java
branches/ddl_sequencer/extensions/dna-sequencer-ddl/src/main/java/org/jboss/dna/sequencer/ddl/statement/Index.java
branches/ddl_sequencer/extensions/dna-sequencer-ddl/src/main/java/org/jboss/dna/sequencer/ddl/statement/Statement.java
branches/ddl_sequencer/extensions/dna-sequencer-ddl/src/main/java/org/jboss/dna/sequencer/ddl/statement/Table.java
branches/ddl_sequencer/extensions/dna-sequencer-ddl/src/main/java/org/jboss/dna/sequencer/ddl/statement/TableConstraint.java
branches/ddl_sequencer/extensions/dna-sequencer-ddl/src/main/java/org/jboss/dna/sequencer/ddl/statement/TableElement.java
branches/ddl_sequencer/extensions/dna-sequencer-ddl/src/main/java/org/jboss/dna/sequencer/ddl/statement/TypedStatement.java
branches/ddl_sequencer/extensions/dna-sequencer-ddl/src/test/
branches/ddl_sequencer/extensions/dna-sequencer-ddl/src/test/java/
branches/ddl_sequencer/extensions/dna-sequencer-ddl/src/test/java/org/
branches/ddl_sequencer/extensions/dna-sequencer-ddl/src/test/java/org/jboss/
branches/ddl_sequencer/extensions/dna-sequencer-ddl/src/test/java/org/jboss/dna/
branches/ddl_sequencer/extensions/dna-sequencer-ddl/src/test/java/org/jboss/dna/sequencer/
branches/ddl_sequencer/extensions/dna-sequencer-ddl/src/test/java/org/jboss/dna/sequencer/ddl/
branches/ddl_sequencer/extensions/dna-sequencer-ddl/src/test/java/org/jboss/dna/sequencer/ddl/datatype/
branches/ddl_sequencer/extensions/dna-sequencer-ddl/src/test/java/org/jboss/dna/sequencer/ddl/datatype/DataTypeParserTest.java
branches/ddl_sequencer/extensions/dna-sequencer-ddl/src/test/java/org/jboss/dna/sequencer/ddl/dialect/
branches/ddl_sequencer/extensions/dna-sequencer-ddl/src/test/java/org/jboss/dna/sequencer/ddl/dialect/DerbyDdlParserTest.java
branches/ddl_sequencer/extensions/dna-sequencer-ddl/src/test/java/org/jboss/dna/sequencer/ddl/dialect/OracleDdlParserTest.java
branches/ddl_sequencer/extensions/dna-sequencer-ddl/src/test/resources/
branches/ddl_sequencer/extensions/dna-sequencer-ddl/src/test/resources/ddl/
branches/ddl_sequencer/extensions/dna-sequencer-ddl/src/test/resources/sql2bnf.aug92.txt
branches/ddl_sequencer/extensions/dna-sequencer-ddl/target/
branches/ddl_sequencer/extensions/dna-sequencer-ddl/target/classes/
branches/ddl_sequencer/extensions/dna-sequencer-ddl/target/classes/ddl/
branches/ddl_sequencer/extensions/dna-sequencer-ddl/target/classes/org/
branches/ddl_sequencer/extensions/dna-sequencer-ddl/target/classes/org/jboss/
branches/ddl_sequencer/extensions/dna-sequencer-ddl/target/classes/org/jboss/dna/
branches/ddl_sequencer/extensions/dna-sequencer-ddl/target/classes/org/jboss/dna/sequencer/
branches/ddl_sequencer/extensions/dna-sequencer-ddl/target/classes/org/jboss/dna/sequencer/ddl/
branches/ddl_sequencer/extensions/dna-sequencer-ddl/target/classes/org/jboss/dna/sequencer/ddl/DdlConstants$DataTypes.class
branches/ddl_sequencer/extensions/dna-sequencer-ddl/target/classes/org/jboss/dna/sequencer/ddl/DdlConstants$StatementStartPhrases.class
branches/ddl_sequencer/extensions/dna-sequencer-ddl/target/classes/org/jboss/dna/sequencer/ddl/DdlConstants.class
branches/ddl_sequencer/extensions/dna-sequencer-ddl/target/classes/org/jboss/dna/sequencer/ddl/DdlTokenStream$DdlTokenizer.class
branches/ddl_sequencer/extensions/dna-sequencer-ddl/target/classes/org/jboss/dna/sequencer/ddl/DdlTokenStream.class
branches/ddl_sequencer/extensions/dna-sequencer-ddl/target/classes/org/jboss/dna/sequencer/ddl/OldDdlTokenizer.class
branches/ddl_sequencer/extensions/dna-sequencer-ddl/target/classes/org/jboss/dna/sequencer/ddl/StandardDdlParser.class
branches/ddl_sequencer/extensions/dna-sequencer-ddl/target/classes/org/jboss/dna/sequencer/ddl/datatype/
branches/ddl_sequencer/extensions/dna-sequencer-ddl/target/classes/org/jboss/dna/sequencer/ddl/dialect/
branches/ddl_sequencer/extensions/dna-sequencer-ddl/target/classes/org/jboss/dna/sequencer/ddl/dialect/Db2DdlParser.class
branches/ddl_sequencer/extensions/dna-sequencer-ddl/target/classes/org/jboss/dna/sequencer/ddl/dialect/DerbyDdlParser$DerbyDataTypeParser.class
branches/ddl_sequencer/extensions/dna-sequencer-ddl/target/classes/org/jboss/dna/sequencer/ddl/dialect/DerbyDdlParser.class
branches/ddl_sequencer/extensions/dna-sequencer-ddl/target/classes/org/jboss/dna/sequencer/ddl/dialect/MySqlDdlParser$MySqlDataTypeParser.class
branches/ddl_sequencer/extensions/dna-sequencer-ddl/target/classes/org/jboss/dna/sequencer/ddl/dialect/MySqlDdlParser.class
branches/ddl_sequencer/extensions/dna-sequencer-ddl/target/classes/org/jboss/dna/sequencer/ddl/dialect/PostgresDdlParser.class
branches/ddl_sequencer/extensions/dna-sequencer-ddl/target/classes/org/jboss/dna/sequencer/ddl/dialect/SqlServerDdlParser.class
branches/ddl_sequencer/extensions/dna-sequencer-ddl/target/classes/org/jboss/dna/sequencer/ddl/dialect/SybaseDdlParser.class
branches/ddl_sequencer/extensions/dna-sequencer-ddl/target/classes/org/jboss/dna/sequencer/ddl/dialect/derby/
branches/ddl_sequencer/extensions/dna-sequencer-ddl/target/classes/org/jboss/dna/sequencer/ddl/dialect/oracle/
branches/ddl_sequencer/extensions/dna-sequencer-ddl/target/classes/org/jboss/dna/sequencer/ddl/statement/
branches/ddl_sequencer/extensions/dna-sequencer-ddl/target/classes/sql2bnf.aug92.txt
branches/ddl_sequencer/extensions/dna-sequencer-ddl/target/logs/
branches/ddl_sequencer/extensions/dna-sequencer-ddl/target/logs/test/
branches/ddl_sequencer/extensions/dna-sequencer-ddl/target/surefire-reports/
branches/ddl_sequencer/extensions/dna-sequencer-ddl/target/surefire-reports/TEST-org.jboss.dna.sequencer.ddl.BasicDdlParserTest.xml
branches/ddl_sequencer/extensions/dna-sequencer-ddl/target/surefire-reports/TEST-org.jboss.dna.sequencer.ddl.datatype.DataTypeParserTest.xml
branches/ddl_sequencer/extensions/dna-sequencer-ddl/target/surefire-reports/TEST-org.jboss.dna.sequencer.ddl.dialect.DerbyDdlParserTest.xml
branches/ddl_sequencer/extensions/dna-sequencer-ddl/target/surefire-reports/TEST-org.jboss.dna.sequencer.ddl.dialect.OracleDdlParserTest.xml
branches/ddl_sequencer/extensions/dna-sequencer-ddl/target/surefire-reports/org.jboss.dna.sequencer.ddl.BasicDdlParserTest.txt
branches/ddl_sequencer/extensions/dna-sequencer-ddl/target/surefire-reports/org.jboss.dna.sequencer.ddl.datatype.DataTypeParserTest.txt
branches/ddl_sequencer/extensions/dna-sequencer-ddl/target/surefire-reports/org.jboss.dna.sequencer.ddl.dialect.DerbyDdlParserTest.txt
branches/ddl_sequencer/extensions/dna-sequencer-ddl/target/surefire-reports/org.jboss.dna.sequencer.ddl.dialect.OracleDdlParserTest.txt
branches/ddl_sequencer/extensions/dna-sequencer-ddl/target/test-classes/
branches/ddl_sequencer/extensions/dna-sequencer-ddl/target/test-classes/ddl/
branches/ddl_sequencer/extensions/dna-sequencer-ddl/target/test-classes/org/
branches/ddl_sequencer/extensions/dna-sequencer-ddl/target/test-classes/org/jboss/
branches/ddl_sequencer/extensions/dna-sequencer-ddl/target/test-classes/org/jboss/dna/
branches/ddl_sequencer/extensions/dna-sequencer-ddl/target/test-classes/org/jboss/dna/sequencer/
branches/ddl_sequencer/extensions/dna-sequencer-ddl/target/test-classes/org/jboss/dna/sequencer/ddl/
branches/ddl_sequencer/extensions/dna-sequencer-ddl/target/test-classes/org/jboss/dna/sequencer/ddl/datatype/
branches/ddl_sequencer/extensions/dna-sequencer-ddl/target/test-classes/org/jboss/dna/sequencer/ddl/datatype/DataTypeParserTest.class
branches/ddl_sequencer/extensions/dna-sequencer-ddl/target/test-classes/org/jboss/dna/sequencer/ddl/dialect/
branches/ddl_sequencer/extensions/dna-sequencer-ddl/target/test-classes/org/jboss/dna/sequencer/ddl/dialect/DerbyDdlParserTest.class
branches/ddl_sequencer/extensions/dna-sequencer-ddl/target/test-classes/org/jboss/dna/sequencer/ddl/dialect/OracleDdlParserTest.class
branches/ddl_sequencer/extensions/dna-sequencer-ddl/target/test-classes/sql2bnf.aug92.txt
Log:
Initial check-in of ddl sequencer and parsing framework
Added: branches/ddl_sequencer/.project
===================================================================
--- branches/ddl_sequencer/.project (rev 0)
+++ branches/ddl_sequencer/.project 2009-10-02 16:13:40 UTC (rev 1280)
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>dna</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ </buildSpec>
+ <natures>
+ </natures>
+</projectDescription>
Property changes on: branches/ddl_sequencer/.project
___________________________________________________________________
Name: svn:mime-type
+ text/plain
Added: branches/ddl_sequencer/extensions/dna-sequencer-ddl/.classpath
===================================================================
--- branches/ddl_sequencer/extensions/dna-sequencer-ddl/.classpath (rev 0)
+++ branches/ddl_sequencer/extensions/dna-sequencer-ddl/.classpath 2009-10-02 16:13:40 UTC (rev 1280)
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+ <classpathentry kind="src" output="target/classes" path="src/main/java"/>
+ <classpathentry kind="src" output="target/test-classes" path="src/test/java"/>
+ <classpathentry kind="src" path="src/test/resources"/>
+ <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
+ <classpathentry kind="con" path="org.maven.ide.eclipse.MAVEN2_CLASSPATH_CONTAINER"/>
+ <classpathentry kind="output" path="target/classes"/>
+</classpath>
Property changes on: branches/ddl_sequencer/extensions/dna-sequencer-ddl/.classpath
___________________________________________________________________
Name: svn:mime-type
+ text/plain
Added: branches/ddl_sequencer/extensions/dna-sequencer-ddl/.project
===================================================================
--- branches/ddl_sequencer/extensions/dna-sequencer-ddl/.project (rev 0)
+++ branches/ddl_sequencer/extensions/dna-sequencer-ddl/.project 2009-10-02 16:13:40 UTC (rev 1280)
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>dna-sequencer-ddl</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>org.eclipse.jdt.core.javabuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.maven.ide.eclipse.maven2Builder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>org.eclipse.jdt.core.javanature</nature>
+ <nature>org.maven.ide.eclipse.maven2Nature</nature>
+ </natures>
+</projectDescription>
Property changes on: branches/ddl_sequencer/extensions/dna-sequencer-ddl/.project
___________________________________________________________________
Name: svn:mime-type
+ text/plain
Added: branches/ddl_sequencer/extensions/dna-sequencer-ddl/pom.xml
===================================================================
--- branches/ddl_sequencer/extensions/dna-sequencer-ddl/pom.xml (rev 0)
+++ branches/ddl_sequencer/extensions/dna-sequencer-ddl/pom.xml 2009-10-02 16:13:40 UTC (rev 1280)
@@ -0,0 +1,88 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <groupId>org.jboss.dna</groupId>
+ <artifactId>dna</artifactId>
+ <version>0.7-SNAPSHOT</version>
+ <relativePath>../..</relativePath>
+ </parent>
+ <!-- The groupId and version values are inherited from parent -->
+ <artifactId>dna-sequencer-ddl</artifactId>
+ <packaging>jar</packaging>
+ <name>JBoss DNA DDL Sequencer</name>
+ <description>JBoss DNA Sequencer that processes DDL files</description>
+ <url>http://labs.jboss.org/dna</url>
+ <dependencies>
+ <!--
+ Common
+ -->
+ <dependency>
+ <groupId>org.jboss.dna</groupId>
+ <artifactId>dna-common</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.jboss.dna</groupId>
+ <artifactId>dna-graph</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.jboss.dna</groupId>
+ <artifactId>dna-common</artifactId>
+ <version>${pom.version}</version>
+ <type>test-jar</type>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.jboss.dna</groupId>
+ <artifactId>dna-graph</artifactId>
+ <version>${pom.version}</version>
+ <type>test-jar</type>
+ <scope>test</scope>
+ </dependency>
+ <!--
+ Testing (note the scope)
+ -->
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.hamcrest</groupId>
+ <artifactId>hamcrest-library</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.mockito</groupId>
+ <artifactId>mockito-all</artifactId>
+ </dependency>
+ <!--
+ Logging (require SLF4J API for compiling, but use Log4J and its SLF4J binding for testing)
+ -->
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-api</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-log4j12</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>log4j</groupId>
+ <artifactId>log4j</artifactId>
+ </dependency>
+ <!--
+ Java Concurrency in Practice annotations
+ -->
+ <dependency>
+ <groupId>net.jcip</groupId>
+ <artifactId>jcip-annotations</artifactId>
+ </dependency>
+ </dependencies>
+ <reporting>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-surefire-report-plugin</artifactId>
+ </plugin>
+ </plugins>
+ </reporting>
+</project>
Property changes on: branches/ddl_sequencer/extensions/dna-sequencer-ddl/pom.xml
___________________________________________________________________
Name: svn:mime-type
+ text/plain
Added: branches/ddl_sequencer/extensions/dna-sequencer-ddl/src/main/java/org/jboss/dna/sequencer/ddl/datatype/DataType.java
===================================================================
--- branches/ddl_sequencer/extensions/dna-sequencer-ddl/src/main/java/org/jboss/dna/sequencer/ddl/datatype/DataType.java (rev 0)
+++ branches/ddl_sequencer/extensions/dna-sequencer-ddl/src/main/java/org/jboss/dna/sequencer/ddl/datatype/DataType.java 2009-10-02 16:13:40 UTC (rev 1280)
@@ -0,0 +1,117 @@
+/*
+ * JBoss DNA (http://www.jboss.org/dna)
+ * 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.
+ * See the AUTHORS.txt file in the distribution for a full listing of
+ * individual contributors.
+ *
+ * JBoss DNA is free software. Unless otherwise indicated, all code in JBoss DNA
+ * is licensed to you 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.
+ *
+ * JBoss DNA 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 software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.dna.sequencer.ddl.datatype;
+
+/**
+ *
+ * @author blafond
+ *
+ */
+public class DataType {
+ private String name;
+ private int length = 0;
+ private int precision = 0;
+ private int scale = 0;
+ private boolean isKMGLength = false;
+ private String kmgValue = null;
+
+ public DataType (String theName) {
+ super();
+ this.name = theName;
+ }
+
+ public DataType (String name, int length) {
+ super();
+ this.name = name;
+ this.length = length;
+ }
+
+
+ public DataType (String name, int precision, int scale) {
+ super();
+ this.name = name;
+ this.precision = precision;
+ this.scale = scale;
+ }
+
+ public String getName() {
+ return this.name;
+ }
+
+ public void setName(String value) {
+ this.name = value;
+ }
+
+ public void setLength(int value) {
+ this.length = value;
+ }
+
+ public int getLength() {
+ return this.length;
+ }
+
+ public void setPrecision(int value) {
+ this.precision = value;
+ }
+
+ public int getPrecision() {
+ return this.precision;
+ }
+
+ public int getScale() {
+ return this.scale;
+ }
+
+ public void setScale(int value) {
+ this.scale = value;
+ }
+
+ @Override
+ public String toString() {
+ StringBuffer result = new StringBuffer(100);
+ result.append("DataType()").append(" ").append(name);
+
+ return result.toString();
+ }
+
+ public boolean isKMGLength() {
+ return isKMGLength;
+ }
+
+ public void setKMGLength(boolean isKMGLength) {
+ this.isKMGLength = isKMGLength;
+ }
+
+ public String getKMGValue() {
+ return kmgValue;
+ }
+
+ public void setKMGValue(String kmgValue) {
+ this.kmgValue = kmgValue;
+ }
+
+
+
+
+}
Property changes on: branches/ddl_sequencer/extensions/dna-sequencer-ddl/src/main/java/org/jboss/dna/sequencer/ddl/datatype/DataType.java
___________________________________________________________________
Name: svn:mime-type
+ text/plain
Added: branches/ddl_sequencer/extensions/dna-sequencer-ddl/src/main/java/org/jboss/dna/sequencer/ddl/datatype/DataTypeParser.java
===================================================================
--- branches/ddl_sequencer/extensions/dna-sequencer-ddl/src/main/java/org/jboss/dna/sequencer/ddl/datatype/DataTypeParser.java (rev 0)
+++ branches/ddl_sequencer/extensions/dna-sequencer-ddl/src/main/java/org/jboss/dna/sequencer/ddl/datatype/DataTypeParser.java 2009-10-02 16:13:40 UTC (rev 1280)
@@ -0,0 +1,593 @@
+/*
+ * JBoss DNA (http://www.jboss.org/dna)
+ * 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.
+ * See the AUTHORS.txt file in the distribution for a full listing of
+ * individual contributors.
+ *
+ * JBoss DNA is free software. Unless otherwise indicated, all code in JBoss DNA
+ * is licensed to you 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.
+ *
+ * JBoss DNA 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 software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.dna.sequencer.ddl.datatype;
+
+import java.math.BigInteger;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.jboss.dna.common.text.ParsingException;
+import org.jboss.dna.sequencer.ddl.DdlConstants;
+import org.jboss.dna.sequencer.ddl.DdlTokenStream;
+
+public class DataTypeParser implements DdlConstants {
+ private static List<String[]> basicCharStringTypes = new ArrayList<String[]>();
+ private static List<String[]> basicNationalCharStringTypes = new ArrayList<String[]>();
+ private static List<String[]> basicBitStringTypes = new ArrayList<String[]>();
+ private static List<String[]> basicExactNumericTypes = new ArrayList<String[]>();
+ private static List<String[]> basicApproxNumericStringTypes = new ArrayList<String[]>();
+ private static List<String[]> basicDateTimeTypes = new ArrayList<String[]>();
+
+ private int defaultLength = 255;
+ private int defaultPrecision = 0;
+ private int defaultScale = 0;
+
+ public DataTypeParser () {
+ super();
+
+ initialize();
+ }
+
+ private void initialize() {
+
+ basicCharStringTypes.add(DataTypes.DTYPE_CHARACTER);
+ basicCharStringTypes.add(DataTypes.DTYPE_CHAR);
+ basicCharStringTypes.add(DataTypes.DTYPE_CHARACTER_VARYING);
+ basicCharStringTypes.add(DataTypes.DTYPE_CHAR_VARYING);
+ basicCharStringTypes.add(DataTypes.DTYPE_VARCHAR);
+
+ basicNationalCharStringTypes.add(DataTypes.DTYPE_NATIONAL_CHARACTER);
+ basicNationalCharStringTypes.add(DataTypes.DTYPE_NATIONAL_CHARACTER_VARYING);
+ basicNationalCharStringTypes.add(DataTypes.DTYPE_NATIONAL_CHAR);
+ basicNationalCharStringTypes.add(DataTypes.DTYPE_NATIONAL_CHAR_VARYING);
+ basicNationalCharStringTypes.add(DataTypes.DTYPE_NCHAR_VARYING);
+
+ basicBitStringTypes.add(DataTypes.DTYPE_BIT);
+ basicBitStringTypes.add(DataTypes.DTYPE_BIT_VARYING);
+
+ basicExactNumericTypes.add(DataTypes.DTYPE_NUMERIC);
+ basicExactNumericTypes.add(DataTypes.DTYPE_DEC);
+ basicExactNumericTypes.add(DataTypes.DTYPE_DECIMAL);
+ basicExactNumericTypes.add(DataTypes.DTYPE_INTEGER);
+ basicExactNumericTypes.add(DataTypes.DTYPE_INT);
+ basicExactNumericTypes.add(DataTypes.DTYPE_SMALLINT);
+
+ basicApproxNumericStringTypes.add(DataTypes.DTYPE_FLOAT);
+ basicApproxNumericStringTypes.add(DataTypes.DTYPE_REAL);
+ basicApproxNumericStringTypes.add(DataTypes.DTYPE_DOUBLE_PRECISION);
+
+ basicDateTimeTypes.add(DataTypes.DTYPE_DATE);
+ basicDateTimeTypes.add(DataTypes.DTYPE_TIME);
+ basicDateTimeTypes.add(DataTypes.DTYPE_TIMESTAMP);
+
+ }
+
+ /**
+ * Method determines if the next set of tokens matches one of the registered data type token sets.
+ *
+ * @param tokens
+ * @return is registered data type
+ * @throws ParsingException
+ */
+ public final boolean isDatatype( DdlTokenStream tokens) throws ParsingException {
+ // Loop through the registered statement start string arrays and look for exact matches.
+
+ for( String[] stmts : basicCharStringTypes ) {
+ if( tokens.matches(stmts) ) return true;
+ }
+
+ for( String[] stmts : basicNationalCharStringTypes ) {
+ if( tokens.matches(stmts) ) return true;
+ }
+
+
+ for( String[] stmts : basicBitStringTypes ) {
+ if( tokens.matches(stmts) ) return true;
+ }
+
+
+ for( String[] stmts : basicExactNumericTypes) {
+ if( tokens.matches(stmts) ) return true;
+ }
+
+
+ for( String[] stmts : basicApproxNumericStringTypes ) {
+ if( tokens.matches(stmts) ) return true;
+ }
+
+
+ for( String[] stmts : basicDateTimeTypes ) {
+ if( tokens.matches(stmts) ) return true;
+ }
+
+ // If no type is found, assume it's a custom type
+ return isCustomDataType(tokens);
+ }
+
+
+ /**
+ * Method determines if the next set of tokens matches one of the registered data type token sets.
+ * @param tokens
+ * @param type
+ * @return is registered data type
+ * @throws ParsingException
+ */
+ private boolean isDatatype( DdlTokenStream tokens, int type) throws ParsingException {
+ // Loop through the registered statement start string arrays and look for exact matches.
+
+ switch( type ) {
+ case DataTypes.DTYPE_CODE_CHAR_STRING: {
+ for( String[] stmts : basicCharStringTypes ) {
+ if( tokens.matches(stmts) ) return true;
+ }
+ } break;
+ case DataTypes.DTYPE_CODE_NCHAR_STRING: {
+ for( String[] stmts : basicNationalCharStringTypes ) {
+ if( tokens.matches(stmts) ) return true;
+ }
+ } break;
+ case DataTypes.DTYPE_CODE_BIT_STRING: {
+ for( String[] stmts : basicBitStringTypes ) {
+ if( tokens.matches(stmts) ) return true;
+ }
+ } break;
+ case DataTypes.DTYPE_CODE_EXACT_NUMERIC: {
+ for( String[] stmts : basicExactNumericTypes ) {
+ if( tokens.matches(stmts) ) return true;
+ }
+ } break;
+ case DataTypes.DTYPE_CODE_APROX_NUMERIC: {
+ for( String[] stmts : basicApproxNumericStringTypes ) {
+ if( tokens.matches(stmts) ) return true;
+ }
+ } break;
+ case DataTypes.DTYPE_CODE_DATE_TIME: {
+ for( String[] stmts : basicDateTimeTypes ) {
+ if( tokens.matches(stmts) ) return true;
+ }
+ } break;
+ }
+
+ return false;
+ }
+
+ /**
+ * Method to determine of next tokens represent a custom data type. Subclasses should override this method and perform
+ * token checks for any non-SQL92 spec'd data types.
+ *
+ * @param tokens
+ * @return is custom data type
+ * @throws ParsingException
+ */
+ protected boolean isCustomDataType( DdlTokenStream tokens ) throws ParsingException {
+ return false;
+ }
+
+ /**
+ * Method which performs the actual parsing of the data type name and applicable values (i.e. VARCHAR(20)) if data type is
+ * found.
+ *
+ * @param tokens
+ * @return the {@link DataType}
+ * @throws ParsingException
+ */
+ public DataType parse( DdlTokenStream tokens ) throws ParsingException {
+ DataType result = null;
+
+ if ( isDatatype(tokens, DataTypes.DTYPE_CODE_CHAR_STRING) ) {
+ result = parseCharStringType(tokens);
+ } else if( isDatatype(tokens, DataTypes.DTYPE_CODE_NCHAR_STRING) ) {
+ result = parseNationalCharStringType(tokens);
+ } else if( isDatatype(tokens, DataTypes.DTYPE_CODE_BIT_STRING) ) {
+ result = parseBitStringType(tokens);
+ } else if( isDatatype(tokens, DataTypes.DTYPE_CODE_EXACT_NUMERIC) ) {
+ result = parseExactNumericType(tokens);
+ } else if( isDatatype(tokens, DataTypes.DTYPE_CODE_APROX_NUMERIC) ) {
+ result = parseApproxNumericType(tokens);
+ } else if( isDatatype(tokens, DataTypes.DTYPE_CODE_DATE_TIME) ) {
+ result = parseDateTimeType(tokens);
+ } else {
+ result = parseCustomType(tokens);
+ }
+
+ return result;
+ }
+
+ /**
+ * Parses SQL-92 Character string data types.
+ *
+ * <character string type> ::=
+ * CHARACTER [ <left paren> <length> <right paren> ]
+ * | CHAR [ <left paren> <length> <right paren> ]
+ * | CHARACTER VARYING <left paren> <length> <right paren>
+ * | CHAR VARYING <left paren> <length> <right paren>
+ * | VARCHAR <left paren> <length> <right paren>
+ *
+ * @param tokens
+ * @return the {@link DataType}
+ * @throws ParsingException
+ */
+ protected DataType parseCharStringType( DdlTokenStream tokens ) throws ParsingException {
+ DataType result = null;
+ String typeName = null;
+
+
+ if( tokens.matches(DataTypes.DTYPE_VARCHAR)) {
+ typeName = tokens.consume(); // "VARCHAR"
+ int length = parseBracketedInteger(tokens);
+
+ result = new DataType(typeName, length);
+ } else {
+
+ typeName = tokens.consume(); // "CHARACTER", "CHAR",
+
+ if( tokens.matches("VARYING")) {
+ typeName = typeName + SPACE + tokens.consume();
+ int length = parseBracketedInteger(tokens);
+
+ result = new DataType(typeName, length);
+ } else {
+ int length = getDefaultLength();
+ if( tokens.matches('(')) {
+ length = parseBracketedInteger(tokens);
+ }
+ result = new DataType(typeName, length);
+ }
+ }
+
+ return result;
+ }
+
+ /**
+ * Parses SQL-92 National Character string data types.
+ *
+ * <national character string type> ::=
+ * NATIONAL CHARACTER [ <left paren> <length> <right paren> ]
+ * | NATIONAL CHAR [ <left paren> <length> <right paren> ]
+ * | NCHAR [ <left paren> <length> <right paren> ]
+ * | NATIONAL CHARACTER VARYING <left paren> <length> <right paren>
+ * | NATIONAL CHAR VARYING <left paren> <length> <right paren>
+ * | NCHAR VARYING <left paren> <length> <right paren>
+ *
+ * @param tokens
+ * @return the {@link DataType}
+ * @throws ParsingException
+ */
+ protected DataType parseNationalCharStringType( DdlTokenStream tokens ) throws ParsingException {
+ DataType result = null;
+ String typeName = null;
+
+ if( tokens.matches(DataTypes.DTYPE_NCHAR_VARYING) ) {
+ typeName = tokens.consume() + SPACE + tokens.consume();
+ int length = parseBracketedInteger(tokens);
+
+ result = new DataType(typeName, length);
+ } else if( tokens.matches("NATIONAL") ) {
+ typeName = tokens.consume();
+ if( tokens.matchesAnyOf("CHAR", "CHARACTER") ) {
+ typeName = typeName + SPACE + tokens.consume();
+ if( tokens.matches("VARYING") ) {
+ typeName = typeName + SPACE + tokens.consume();
+ int length = parseBracketedInteger(tokens);
+
+ result = new DataType(typeName, length);
+ } else {
+ result = new DataType(typeName, getDefaultLength());
+ }
+ }
+ }
+
+ return result;
+ }
+
+ /**
+ * Parses SQL-92 Bit string data types.
+ *
+ * <bit string type> ::=
+ * BIT [ <left paren> <length> <right paren> ]
+ * | BIT VARYING <left paren> <length> <right paren>
+ *
+ *
+ * @param tokens
+ * @return the {@link DataType}
+ * @throws ParsingException
+ */
+ protected DataType parseBitStringType( DdlTokenStream tokens ) throws ParsingException {
+ DataType result = null;
+
+ String typeName = tokens.consume(); // "BIT"
+
+ if( tokens.matches("VARYING") ) {
+ typeName = typeName + SPACE + tokens.consume();
+ int length = parseBracketedInteger(tokens);
+
+ result = new DataType(typeName, length);
+ } else {
+ result = new DataType(typeName, getDefaultLength());
+ }
+
+ return result;
+ }
+
+ /**
+ * Parses SQL-92 Exact numeric data types.
+ *
+ * <exact numeric type> ::=
+ * NUMERIC [ <left paren> <precision> [ <comma> <scale> ] <right paren> ]
+ * | DECIMAL [ <left paren> <precision> [ <comma> <scale> ] <right paren> ]
+ * | DEC [ <left paren> <precision> [ <comma> <scale> ] <right paren> ]
+ * | INTEGER
+ * | INT
+ * | SMALLINT
+ *
+ * @param tokens
+ * @return the {@link DataType}
+ * @throws ParsingException
+ */
+ protected DataType parseExactNumericType( DdlTokenStream tokens ) throws ParsingException {
+ DataType result = null;
+ String typeName = null;
+
+ if( tokens.matchesAnyOf("INTEGER", "INT", "SMALLINT") ) {
+ typeName = tokens.consume();
+ result = new DataType(typeName);
+ } else if( tokens.matchesAnyOf("NUMERIC", "DECIMAL", "DEC")) {
+ typeName = tokens.consume();
+ int precision = 0;
+ int scale = 0;
+ if( tokens.matches('(')) {
+ tokens.consume('(');
+ precision = parseInteger(tokens);
+ if( tokens.canConsume(',') ) {
+ scale = parseInteger(tokens);
+ } else {
+ scale = getDefaultScale();
+ }
+ tokens.consume(')');
+ } else {
+ precision = getDefaultPrecision();
+ scale = getDefaultScale();
+ }
+ result = new DataType(typeName, precision, scale);
+ }
+
+ return result;
+ }
+
+ /**
+ * Parses SQL-92 Approximate numeric data types.
+ *
+ * <approximate numeric type> ::=
+ * FLOAT [ <left paren> <precision> <right paren> ]
+ * | REAL
+ * | DOUBLE PRECISION
+ *
+ * @param tokens
+ * @return the {@link DataType}
+ * @throws ParsingException
+ */
+ protected DataType parseApproxNumericType( DdlTokenStream tokens ) throws ParsingException {
+ DataType result = null;
+ String typeName = null;
+
+ if( tokens.matches(DataTypes.DTYPE_REAL) ) {
+ typeName = tokens.consume();
+ result = new DataType(typeName);
+ } else if( tokens.matches(DataTypes.DTYPE_DOUBLE_PRECISION) ) {
+ typeName = tokens.consume() + SPACE + tokens.consume();
+ result = new DataType(typeName);
+ } else if( tokens.matches(DataTypes.DTYPE_FLOAT)) {
+ typeName = tokens.consume();
+ int precision = 0;
+ if( tokens.matches('(')) {
+ precision = parseBracketedInteger(tokens);
+ }
+ result = new DataType(typeName, precision, 0);
+ }
+
+ return result;
+ }
+
+
+ /**
+ * Parses SQL-92 Date and Time data types.
+ *
+ * <datetime type> ::=
+ * DATE
+ * | TIME [ <left paren> <time precision> <right paren> ]
+ * [ WITH TIME ZONE ]
+ * | TIMESTAMP [ <left paren> <timestamp precision> <right paren> ]
+ * [ WITH TIME ZONE ]
+ *
+ * @param tokens
+ * @return the {@link DataType}
+ * @throws ParsingException
+ */
+ protected DataType parseDateTimeType( DdlTokenStream tokens ) throws ParsingException {
+ DataType result = null;
+ String typeName = null;
+
+ if( tokens.matches(DataTypes.DTYPE_DATE) ) {
+ typeName = tokens.consume();
+ result = new DataType(typeName);
+ } else if( tokens.matches(DataTypes.DTYPE_TIME)) {
+ typeName = tokens.consume();
+ int precision = 0;
+ if( tokens.matches('(')) {
+ precision = parseBracketedInteger(tokens);
+ }
+ result = new DataType(typeName, precision, 0);
+ } else if( tokens.matches(DataTypes.DTYPE_TIMESTAMP)) {
+ typeName = tokens.consume();
+ int precision = 0;
+ if( tokens.matches('(')) {
+ precision = parseBracketedInteger(tokens);
+ }
+ result = new DataType(typeName, precision, 0);
+ }
+
+ return result;
+ }
+
+ /**
+ * General catch-all data type parsing method that sub-classes can override to parse database-specific data types.
+ *
+ * @param tokens
+ * @return the {@link DataType}
+ * @throws ParsingException
+ */
+ protected DataType parseCustomType( DdlTokenStream tokens ) throws ParsingException {
+ return null;
+ }
+
+ /**
+ *
+ * @return integer default value for length
+ */
+ public int getDefaultLength() {
+ return defaultLength;
+ }
+
+ /**
+ *
+ * @param defaultLength
+ */
+ public void setDefaultLength(int defaultLength) {
+ this.defaultLength = defaultLength;
+ }
+
+ /**
+ *
+ * @return integer default value for precision
+ */
+ public int getDefaultPrecision() {
+ return defaultPrecision;
+ }
+
+ /**
+ *
+ * @param defaultPrecision
+ */
+ public void setDefaultPrecision(int defaultPrecision) {
+ this.defaultPrecision = defaultPrecision;
+ }
+
+ /**
+ *
+ * @return integer default value for scale
+ */
+ public int getDefaultScale() {
+ return defaultScale;
+ }
+
+ /**
+ *
+ * @param defaultScale
+ */
+ public void setDefaultScale(int defaultScale) {
+ this.defaultScale = defaultScale;
+ }
+
+ /**
+ * Returns an integer value from the input token stream assuming the integer is not bracketed with parenthesis.
+ *
+ *
+ * @param tokens
+ * @return integer value
+ */
+ protected int parseInteger( DdlTokenStream tokens ) {
+ String value = tokens.consume();
+
+ if( isKMGInteger(value) ) {
+ value = value.substring(0, value.length()-1);
+ }
+
+ return new BigInteger(value).intValue();
+ }
+
+ /**
+ * Returns an integer value from the input token stream assuming the integer is bracketed with parenthesis.
+ *
+ * Example: (255)
+ *
+ * @param tokens
+ * @return integer value
+ */
+ protected int parseBracketedInteger( DdlTokenStream tokens ) {
+ tokens.consume('(');
+ int length = parseInteger(tokens);
+ tokens.consume(')');
+
+ return length;
+ }
+
+ /**
+ * Returns the whether or not a tokenized string is a complex BLOB or CLOB length value ending in K, M or G
+ *
+ * Example: BLOB (100M) or CLOB(64K)
+ *
+ * @param value
+ * @return true if value ends with M, K or G
+ */
+ protected boolean isKMGInteger( String value ) {
+ return ( value.endsWith("M") || value.endsWith("K") || value.endsWith("G"));
+ }
+
+ /**
+ *
+ * Returns the integer value of the input string.
+ *
+ * Handles both straight integer string or complex KMG (CLOB or BLOB) value.
+ *
+ * Throws {@link NumberFormatException} if a valid integer is not found.
+ *
+ * @param value
+ * @return integer value
+ */
+ protected int parseInteger( String value ) {
+ if( isKMGInteger(value) ) {
+ value = value.substring(0, value.length()-1);
+ }
+
+ return new BigInteger(value).intValue();
+ }
+
+ /**
+ * Returns the K, M or G string value of a tokenized complex BLOB or CLOB length value
+ *
+ * Example: BLOB (100M) or CLOB(64K)
+ *
+ * @param value
+ * @return K, M or G or NULL if not found.
+ */
+ protected String getKMG( String value ) {
+ if( value.endsWith("M")) return "M";
+ if( value.endsWith("K")) return "K";
+ if( value.endsWith("G")) return "G";
+
+ return null;
+ }
+
+
+}
Property changes on: branches/ddl_sequencer/extensions/dna-sequencer-ddl/src/main/java/org/jboss/dna/sequencer/ddl/datatype/DataTypeParser.java
___________________________________________________________________
Name: svn:mime-type
+ text/plain
Added: branches/ddl_sequencer/extensions/dna-sequencer-ddl/src/main/java/org/jboss/dna/sequencer/ddl/dialect/Db2DdlParser.java
===================================================================
--- branches/ddl_sequencer/extensions/dna-sequencer-ddl/src/main/java/org/jboss/dna/sequencer/ddl/dialect/Db2DdlParser.java (rev 0)
+++ branches/ddl_sequencer/extensions/dna-sequencer-ddl/src/main/java/org/jboss/dna/sequencer/ddl/dialect/Db2DdlParser.java 2009-10-02 16:13:40 UTC (rev 1280)
@@ -0,0 +1,100 @@
+package org.jboss.dna.sequencer.ddl.dialect;
+
+import org.jboss.dna.sequencer.ddl.StandardDdlParser;
+
+
+
+public class Db2DdlParser extends StandardDdlParser {
+ private static final String[] COMMENT_ON = {"COMMENT", "ON"};
+
+
+ /*
+
+ * ===========================================================================================================================
+ * Data Types
+
+ |--+-SMALLINT---------------------------------------------------------------+--|
+ +-+-INTEGER-+------------------------------------------------------------+
+ | '-INT-----' |
+ +-BIGINT-----------------------------------------------------------------+
+ +-+-FLOAT--+---------------+-+-------------------------------------------+
+ | | '-(--integer--)-' | |
+ | +-REAL---------------------+ |
+ | | .-PRECISION-. | |
+ | '-DOUBLE--+-----------+----' |
+ +-+-DECIMAL-+--+-----------------------------+---------------------------+
+ | +-DEC-----+ '-(--integer--+----------+--)-' |
+ | +-NUMERIC-+ '-,integer-' |
+ | '-NUM-----' |
+ +-+-+-CHARACTER-+--+-----------+--------------+--+---------------------+-+
+ | | '-CHAR------' '-(integer)-' | | (1) | |
+ | +-+-VARCHAR----------------+--(--integer--)-+ '--------FOR BIT DATA-' |
+ | | '-+-CHARACTER-+--VARYING-' | |
+ | | '-CHAR------' | |
+ | '-LONG VARCHAR------------------------------' |
+ +-+-+-BLOB----------------+---------+--+----------------------+----------+
+ | | '-BINARY LARGE OBJECT-' | '-2 (--2 integer--+---+--2 )-' |
+ | +-+-CLOB------------------------+-+ +-2 K-+ |
+ | | '-+-CHARACTER-+--LARGE OBJECT-' | +-2 M-+ |
+ | | '-CHAR------' | '-2 G-' |
+ | '-DBCLOB--------------------------' |
+ +-GRAPHIC--+-----------+-------------------------------------------------+
+ | '-(integer)-' |
+ +-VARGRAPHIC--(integer)--------------------------------------------------+
+ +-LONG VARGRAPHIC--------------------------------------------------------+
+ +-DATE-------------------------------------------------------------------+
+ +-TIME-------------------------------------------------------------------+
+ +-TIMESTAMP--------------------------------------------------------------+
+ +-DATALINK--+---------------+--------------------------------------------+
+ | '-(--integer--)-' |
+ +-distinct-type-name-----------------------------------------------------+
+ +-structured-type-name---------------------------------------------------+
+ '-REF--(type-name2)------------------------------------------------------'
+
+
+
+ * ===========================================================================================================================
+ * Data Definition Statements
+ ALLOCATE CURSOR
+ ALTER [BUFFERPON | (DATABASE PARTITION GROUP) | DATABASE | FUNCTION | METHOD | NICKNAME | PROCEDURE | SEQUENCE | SERVER
+ | TABLE | TABLESPACE | TYPE | (USER MAPPING) | VIEW | WRAPPER]
+ ASSOCIATE LOCATORS
+ CASE
+ COMMENT ON
+ COMMIT [WORK]
+ CREATE [ALIAS | BUFFERPOOL | (DATABASE PARTITION GROUP) | (DISTINCT TYPE) | (EVENT MONITOR) | FUNCTION | (FUNCTION MAPPING)
+ | INDEX | METHOD | NICKNAME | PROCEDURE | SCHEMA | SEQUENCE | SERVER | TABLE | TABLESPACE | TRANSFORM | TRIGGER | TYPE
+ | (TYPE MAPPING) | (USER MAPPING) | VIEW | WRAPPER]
+ DECLARE GLOBAL TEMPORARY TABLE
+ DELETE FROM
+ DROP [ALIAS | BUFFERPOOL | (DATABASE PARTITION GROUP) | (EVENT MONITOR) | FUNCTION | (SPECIFIC FUNCTION) | (FUNCTION MAPPING)
+ | INDEX | (INDEX EXTENSION) | METHOD | (SPECIFIC METHOD) | NICKNAME | PACKAGE | PROCEDURE | (SPECIFIC PROCEDURE) | SCHEMA
+ | SEQUENCE | SERVER | TABLE | (TABLE HIERARCHY) | TABLESPACE[S] | TRANSFORM[S] | TRIGGER | TYPE | (TYPE MAPPING)
+ | (USER MAPPING) | (USER MAPPING FOR) | VIEW | (VIEW HIERARCHY) | WRAPPER]
+
+ */
+
+ private static final String TERMINATOR = "%";
+
+ public Db2DdlParser() {
+ super();
+ initialize();
+ }
+
+
+ private void initialize() {
+ registerStatementStartPhrase(COMMENT_ON);
+ setTerminator(TERMINATOR);
+ }
+ // ===========================================================================================================================
+ // ===========================================================================================================================
+
+
+ // ===========================================================================================================================
+ // ===========================================================================================================================
+
+
+ // ===========================================================================================================================
+ // ===========================================================================================================================
+
+}
Property changes on: branches/ddl_sequencer/extensions/dna-sequencer-ddl/src/main/java/org/jboss/dna/sequencer/ddl/dialect/Db2DdlParser.java
___________________________________________________________________
Name: svn:mime-type
+ text/plain
Added: branches/ddl_sequencer/extensions/dna-sequencer-ddl/src/main/java/org/jboss/dna/sequencer/ddl/dialect/DerbyDdlParser.java
===================================================================
--- branches/ddl_sequencer/extensions/dna-sequencer-ddl/src/main/java/org/jboss/dna/sequencer/ddl/dialect/DerbyDdlParser.java (rev 0)
+++ branches/ddl_sequencer/extensions/dna-sequencer-ddl/src/main/java/org/jboss/dna/sequencer/ddl/dialect/DerbyDdlParser.java 2009-10-02 16:13:40 UTC (rev 1280)
@@ -0,0 +1,630 @@
+package org.jboss.dna.sequencer.ddl.dialect;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import org.jboss.dna.common.text.ParsingException;
+import org.jboss.dna.sequencer.ddl.DdlTokenStream;
+import org.jboss.dna.sequencer.ddl.StandardDdlParser;
+import org.jboss.dna.sequencer.ddl.DdlTokenStream.DdlTokenizer;
+import org.jboss.dna.sequencer.ddl.datatype.DataType;
+import org.jboss.dna.sequencer.ddl.datatype.DataTypeParser;
+import org.jboss.dna.sequencer.ddl.dialect.derby.DerbyDdlConstants;
+import org.jboss.dna.sequencer.ddl.statement.AlterTable;
+import org.jboss.dna.sequencer.ddl.statement.Column;
+import org.jboss.dna.sequencer.ddl.statement.Index;
+import org.jboss.dna.sequencer.ddl.statement.Statement;
+import org.jboss.dna.sequencer.ddl.statement.TableConstraint;
+import org.jboss.dna.sequencer.ddl.statement.TypedStatement;
+
+public class DerbyDdlParser extends StandardDdlParser implements DerbyDdlConstants {
+
+ static List<String[]> derbyDataTypeStrings = new ArrayList<String[]>();
+
+ private static final String TERMINATOR = DEFAULT_TERMINATOR;
+
+ public DerbyDdlParser() {
+ setDatatypeParser(new DerbyDataTypeParser());
+
+ initialize();
+ }
+
+
+ private void initialize() {
+
+
+ setDoUseTerminator(true);
+
+ setTerminator(TERMINATOR);
+
+ derbyDataTypeStrings.addAll(DerbyDataTypes.CUSTOM_DATATYPE_START_PHRASES);
+ }
+
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.jboss.dna.sequencer.ddl.StandardDdlParser#registerWords(org.jboss.dna.sequencer.ddl.DdlTokenStream)
+ */
+ @Override
+ protected void registerWords(DdlTokenStream tokens) {
+ tokens.registerKeyWords(CUSTOM_KEYWORDS);
+
+ tokens.registerStatementStartPhrase(DerbyStatementStartPhrases.ALTER_PHRASES);
+ tokens.registerStatementStartPhrase(DerbyStatementStartPhrases.CREATE_PHRASES);
+ tokens.registerStatementStartPhrase(DerbyStatementStartPhrases.DROP_PHRASES);
+ tokens.registerStatementStartPhrase(DerbyStatementStartPhrases.SET_PHRASES);
+ tokens.registerStatementStartPhrase(DerbyStatementStartPhrases.MISC_PHRASES);
+ super.registerWords(tokens);
+ }
+
+
+ /**
+ *
+ * {@inheritDoc}
+ *
+ * @see org.jboss.dna.sequencer.ddl.StandardDdlParser#parseCustomStatement(org.jboss.dna.sequencer.ddl.DdlTokenStream)
+ */
+ @Override
+ protected Statement parseCustomStatement(DdlTokenStream tokens)
+ throws ParsingException {
+ Statement result = super.parseCustomStatement(tokens);
+ if( result == null ) {
+ if( tokens.canConsume(DerbyStatementStartPhrases.STMT_LOCK_TABLE) ) {
+ result = parseIgnorableStatement(tokens, getStatementTypeName(DerbyStatementStartPhrases.STMT_LOCK_TABLE));
+ } else if( tokens.canConsume(DerbyStatementStartPhrases.STMT_RENAME_TABLE) ) {
+ result = parseIgnorableStatement(tokens, getStatementTypeName(DerbyStatementStartPhrases.STMT_RENAME_TABLE));
+ } else if( tokens.canConsume(DerbyStatementStartPhrases.STMT_RENAME_INDEX) ) {
+ result = parseIgnorableStatement(tokens, getStatementTypeName(DerbyStatementStartPhrases.STMT_RENAME_INDEX));
+ } else if( tokens.canConsume(DerbyStatementStartPhrases.STMT_DECLARE_GLOBAL_TEMP_TABLE) ) {
+ result = parseIgnorableStatement(tokens, getStatementTypeName(DerbyStatementStartPhrases.STMT_DECLARE_GLOBAL_TEMP_TABLE));
+ }
+ }
+ return result;
+ }
+
+ /**
+ *
+ * {@inheritDoc}
+ *
+ * @see org.jboss.dna.sequencer.ddl.StandardDdlParser#parseCreateStatement(org.jboss.dna.sequencer.ddl.DdlTokenStream, boolean)
+ */
+ @Override
+ protected Statement parseCreateStatement(DdlTokenStream tokens, boolean inSchema)
+ throws ParsingException {
+ Statement result = null;
+
+ if( tokens.matches(DerbyStatementStartPhrases.STMT_CREATE_INDEX)
+ || tokens.matches(DerbyStatementStartPhrases.STMT_CREATE_UNIQUE_INDEX) ) {
+ result = parseCreateIndex(tokens);
+ } else if( tokens.canConsume(DerbyStatementStartPhrases.STMT_CREATE_FUNCTION) ) {
+ result = parseIgnorableStatement(tokens, getStatementTypeName(DerbyStatementStartPhrases.STMT_CREATE_FUNCTION));
+ } else if( tokens.canConsume(DerbyStatementStartPhrases.STMT_CREATE_PROCEDURE) ) {
+ result = parseIgnorableStatement(tokens, getStatementTypeName(DerbyStatementStartPhrases.STMT_CREATE_PROCEDURE));
+ } else if( tokens.canConsume(DerbyStatementStartPhrases.STMT_CREATE_ROLE) ) {
+ result = parseIgnorableStatement(tokens, getStatementTypeName(DerbyStatementStartPhrases.STMT_CREATE_ROLE));
+ } else if( tokens.canConsume(DerbyStatementStartPhrases.STMT_CREATE_SYNONYM) ) {
+ result = parseIgnorableStatement(tokens, getStatementTypeName(DerbyStatementStartPhrases.STMT_CREATE_SYNONYM));
+ } else if( tokens.canConsume(DerbyStatementStartPhrases.STMT_CREATE_TRIGGER) ) {
+ result = parseIgnorableStatement(tokens, getStatementTypeName(DerbyStatementStartPhrases.STMT_CREATE_TRIGGER));
+ }
+
+ if( result == null ) {
+ result = super.parseCreateStatement(tokens, inSchema);
+ }
+
+ return result;
+ }
+
+ /**
+ * Parses DDL CREATE INDEX {@link Statement}
+ *
+ * @param tokens
+ * @return the parsed CREATE INDEX {@link Statement}
+ * @throws ParsingException
+ */
+ protected Statement parseCreateIndex( DdlTokenStream tokens ) throws ParsingException {
+ // CREATE [UNIQUE] INDEX index-Name
+ // ON table-Name ( Simple-column-Name [ ASC | DESC ] [ , Simple-column-Name [ ASC | DESC ]] * )
+ tokens.consume(); // CREATE
+ boolean isUnique = tokens.canConsume("UNIQUE");
+ tokens.canConsume("BITMAP");
+ tokens.consume("INDEX");
+ String indexName = consumeIdentifier(tokens);
+ tokens.consume("ON");
+ tokens.canConsume("CLUSTER");
+ String tableName = parseName(tokens);
+
+ //System.out.println(" >> PARSING Create INDEX >> Name = " + indexName + " For TABLE = " + tableName);
+
+ List<String> columnNameList = new ArrayList<String>();
+ try {
+ if( tokens.matches('(')) {
+ tokens.consume();
+ columnNameList = parseColumnNameList(tokens);
+ tokens.consume(')');
+ }
+ } catch (ParsingException e) {
+ // Give up on parsing, probably a nested function (i.e. banned (lower(banned_name));
+ parseUntilTerminator(tokens);
+ }
+ Index newIndex = new Index(indexName, tableName, columnNameList);
+ newIndex.setUnique(isUnique);
+
+ consumeTerminator(tokens);
+
+ return newIndex;
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.jboss.dna.sequencer.ddl.StandardDdlParser#parseDropStatement(org.jboss.dna.sequencer.ddl.DdlTokenStream)
+ */
+ @Override
+ protected Statement parseDropStatement(DdlTokenStream tokens)
+ throws ParsingException {
+ Statement result = null;
+
+ if( tokens.canConsume(DerbyStatementStartPhrases.STMT_DROP_FUNCTION) ) {
+ result = parseIgnorableStatement(tokens, getStatementTypeName(DerbyStatementStartPhrases.STMT_DROP_FUNCTION));
+ } else if( tokens.canConsume(DerbyStatementStartPhrases.STMT_DROP_INDEX) ) {
+ result = parseIgnorableStatement(tokens, getStatementTypeName(DerbyStatementStartPhrases.STMT_DROP_INDEX));
+ } else if( tokens.canConsume(DerbyStatementStartPhrases.STMT_DROP_PROCEDURE) ) {
+ result = parseIgnorableStatement(tokens, getStatementTypeName(DerbyStatementStartPhrases.STMT_DROP_PROCEDURE));
+ } else if( tokens.canConsume(DerbyStatementStartPhrases.STMT_DROP_ROLE) ) {
+ result = parseIgnorableStatement(tokens, getStatementTypeName(DerbyStatementStartPhrases.STMT_DROP_ROLE));
+ } else if( tokens.canConsume(DerbyStatementStartPhrases.STMT_DROP_SYNONYM) ) {
+ result = parseIgnorableStatement(tokens, getStatementTypeName(DerbyStatementStartPhrases.STMT_DROP_SYNONYM));
+ } else if( tokens.canConsume(DerbyStatementStartPhrases.STMT_DROP_TRIGGER) ) {
+ result = parseIgnorableStatement(tokens, getStatementTypeName(DerbyStatementStartPhrases.STMT_DROP_TRIGGER));
+ }
+
+ if( result == null ) {
+ result = super.parseDropStatement(tokens);
+ }
+
+ return result;
+ }
+
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.jboss.dna.sequencer.ddl.StandardDdlParser#parseGrantStatement(org.jboss.dna.sequencer.ddl.DdlTokenStream)
+ */
+ @Override
+ protected Statement parseGrantStatement(DdlTokenStream tokens)
+ throws ParsingException {
+ if( tokens.matches(GRANT, DdlTokenStream.ANY_VALUE, "TO")) {
+ tokens.consume(GRANT);
+ String privilege = tokens.consume();
+ tokens.consume("TO");
+ String toValue = tokens.consume();
+ Statement stmt = new TypedStatement();
+ String value = parseUntilTerminator(tokens);
+ stmt.setValue(value);
+ stmt.setType("GRANT" + SPACE + privilege + SPACE + "TO" + SPACE + toValue);
+ consumeTerminator(tokens);
+ return stmt;
+ }
+ if( tokens.matches(GRANT, DdlTokenStream.ANY_VALUE, "ON")) {
+ tokens.consume(GRANT);
+ String privilege = tokens.consume();
+ tokens.consume("ON");
+ String toValue = tokens.consume();
+ Statement stmt = new TypedStatement();
+ String value = parseUntilTerminator(tokens);
+ stmt.setValue(value);
+ stmt.setType("GRANT" + SPACE + privilege + SPACE + "ON" + SPACE + toValue);
+ consumeTerminator(tokens);
+ return stmt;
+ }
+ if( tokens.matches(GRANT, CREATE) ||
+ tokens.matches(GRANT, ALTER) ||
+ tokens.matches(GRANT, DROP) ||
+ tokens.matches(GRANT, "EXECUTE") ||
+ tokens.matches(GRANT, "MANAGE") ||
+ tokens.matches(GRANT, "QUERY") ||
+ tokens.matches(GRANT, "ON", "COMMIT") ||
+ tokens.matches(GRANT, "ANY") ||
+ tokens.matches(GRANT, "SELECT") ||
+ tokens.matches(GRANT, "RESTRICTED") ||
+ tokens.matches(GRANT, "FLASHBACK") ||
+ tokens.matches(GRANT, "GLOBAL") ||
+ tokens.matches(GRANT, "DEBUG") ||
+ tokens.matches(GRANT, "GLOBAL") ||
+ tokens.matches(GRANT, "ADVISOR") ||
+ tokens.matches(GRANT, "ADMINISTER") ||
+ tokens.matches(GRANT, "BACKUP") ||
+ tokens.matches(GRANT, "LOCK") ||
+ tokens.matches(GRANT, "UPDATE") ||
+ tokens.matches(GRANT, "DELETE") ||
+ tokens.matches(GRANT, "INSERT") ||
+ tokens.matches(GRANT, "UNLIMITED") ||
+ tokens.matches(GRANT, "UNDER") ||
+ tokens.matches(GRANT, "ANALYZE") ||
+ tokens.matches(GRANT, "AUDIT") ||
+ tokens.matches(GRANT, "COMMENT") ||
+ tokens.matches(GRANT, "EXEMPT") ||
+ tokens.matches(GRANT, "FORCE") ||
+ tokens.matches(GRANT, "RESUMABLE") ||
+ tokens.matches(GRANT, "SYSDBA") ||
+ tokens.matches(GRANT, "REFERENCES") ||
+ tokens.matches(GRANT, "SYSOPER") ||
+ tokens.matches(GRANT, "WRITE") ||
+ tokens.matches(GRANT, "EXECUTE") ) {
+ tokens.consume(GRANT);
+ String nextTok = tokens.consume() + SPACE + tokens.consume() + SPACE + tokens.consume();
+ Statement stmt = new TypedStatement();
+ String value = parseUntilTerminator(tokens);
+ stmt.setValue(value);
+ stmt.setType("GRANT" + " " + nextTok);
+ consumeTerminator(tokens);
+ return stmt;
+ }
+
+
+ return null;
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.jboss.dna.sequencer.ddl.StandardDdlParser#parseAlterTableStatement(org.jboss.dna.sequencer.ddl.DdlTokenStream)
+ */
+ @Override
+ protected Statement parseAlterTableStatement(DdlTokenStream tokens)
+ throws ParsingException {
+
+ // ALTER TABLE table-Name
+ // {
+ // ADD COLUMN column-definition |
+ // ADD CONSTRAINT clause |
+ // DROP [ COLUMN ] column-name [ CASCADE | RESTRICT ] |
+ // DROP { PRIMARY KEY | FOREIGN KEY constraint-name | UNIQUE constraint-name | CHECK constraint-name | CONSTRAINT constraint-name } |
+ // ALTER [ COLUMN ] column-alteration |
+ // LOCKSIZE { ROW | TABLE }
+ // }
+
+ tokens.consume(); // consumes 'ALTER'
+ tokens.consume("TABLE");
+ String tableName = parseName(tokens);
+
+ //System.out.println(" >> PARSING ALTER STATEMENT >> TABLE Name = " + tableName);
+
+ AlterTable alterTableStatement = new AlterTable(tableName);
+
+ if( tokens.canConsume("ADD") ) {
+ TableConstraint constraint = parseTableConstraint(tokens);
+ if( constraint != null ) {
+ alterTableStatement.addConstraint(constraint);
+ } else {
+ // This segment can also be enclosed in "()" brackets to handle multiple Column ADDs
+ if( tokens.matches('(')) {
+ List<Column> columns = parseColumns(tokens);
+ for( Column newColumn : columns ) {
+ alterTableStatement.addColumn(newColumn);
+ }
+ } else {
+ // Assume single ADD COLUMN
+ Column newColumn = parseSingleTerminatedColumnDefinition(tokens);
+
+ alterTableStatement.addColumn(newColumn);
+ }
+ }
+
+ } else if( tokens.canConsume("DROP")) {
+ // DROP { PRIMARY KEY | FOREIGN KEY constraint-name | UNIQUE constraint-name | CHECK constraint-name | CONSTRAINT constraint-name }
+ if( tokens.canConsume("PRIMARY", "KEY") ||
+ tokens.canConsume("FOREIGN", "KEY") ||
+ tokens.canConsume("UNIQUE") ||
+ tokens.canConsume("CHECK") ||
+ tokens.canConsume("CONSTRAINT") ) {
+ parseName(tokens); // constraint name
+ } else {
+ // DROP [ COLUMN ] column-name [ CASCADE | RESTRICT ]
+ tokens.canConsume("COLUMN"); // "COLUMN" is optional
+
+ String columnName = parseName(tokens);
+ alterTableStatement.addDroppedColumnName(columnName);
+
+ tokens.canConsume("CASCADE");
+ tokens.canConsume("RESTRICT");
+ }
+ } else if( tokens.canConsume("ALTER")) {
+ // column-alteration
+ //
+ // column-Name SET DATA TYPE VARCHAR(integer) |
+ // column-Name SET DATA TYPE VARCHAR FOR BIT DATA(integer) |
+ // column-name SET INCREMENT BY integer-constant |
+ // column-name RESTART WITH integer-constant |
+ // column-name [ NOT ] NULL |
+ // column-name [ WITH | SET ] DEFAULT default-value |
+ // column-name DROP DEFAULT
+
+ tokens.canConsume("COLUMN");
+ parseName(tokens);
+ if( tokens.matches("DEFAULT") ) {
+ parseDefaultClause(tokens);
+ } else if( tokens.canConsume("SET")) {
+ if( tokens.canConsume("DATA", "TYPE" ) ) {
+ tokens.consume("VARCHAR");
+ tokens.canConsume("FOR", "BIT", "DATA");
+ tokens.consume("(", DdlTokenStream.ANY_VALUE, ")");
+ } else if( tokens.canConsume("INCREMENT") ) {
+ tokens.consume("BY", DdlTokenStream.ANY_VALUE);
+ }
+ parseDefaultClause(tokens);
+ } else if( tokens.canConsume("WITH") ) {
+ parseDefaultClause(tokens);
+ } else {
+ tokens.canConsume("RESTART", "WITH", DdlTokenStream.ANY_VALUE);
+ tokens.canConsume("DROP", "DEFAULT");
+ tokens.canConsume("NOT", "NULL");
+ tokens.canConsume("NULL");
+ }
+
+ } else if( tokens.canConsume("LOCKSIZE")) {
+ tokens.canConsume("ROWS");
+ tokens.canConsume("TABLE");
+ }
+
+ consumeTerminator(tokens);
+
+ return alterTableStatement;
+ }
+
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.jboss.dna.sequencer.ddl.StandardDdlParser#parseColumnDefinition(org.jboss.dna.sequencer.ddl.DdlTokenStream)
+ */
+ @Override
+ protected Column parseColumnDefinition(DdlTokenStream tokens) throws ParsingException {
+ // column-definition
+ //
+ // Simple-column-Name DataType
+ // [ Column-level-constraint ]*
+ // [ [ WITH ] DEFAULT { ConstantExpression | NULL } |generated-column-spec ]
+ // [ Column-level-constraint ]*
+
+ // generated-column-spec
+ //
+ // [ GENERATED { ALWAYS | BY DEFAULT } AS IDENTITY [ ( START WITH IntegerConstant [ ,INCREMENT BY IntegerConstant] ) ] ] ]
+
+ // EXAMPLE COLUMNS
+ // (i INT GENERATED BY DEFAULT AS IDENTITY (START WITH 2, INCREMENT BY 1),
+ // ch CHAR(50));
+
+ tokens.canConsume("COLUMN"); // FOR ALTER TABLE ADD [COLUMN] case
+ String columnName = parseName(tokens);
+ DataType datatype = getDatatypeParser().parse(tokens);
+
+ Column newColumn = new Column(columnName, datatype);
+
+ // Now clauses and constraints can be defined in any order, so we need to keep parsing until we get to a comma
+
+ while( tokens.hasNext() && !tokens.matches(',')) {
+ String defaultValue = parseDefaultClause(tokens);
+ if( defaultValue != null ) {
+ newColumn.setDefaultValue(defaultValue);
+ } else {
+ parseGeneratedColumnSpecClause(tokens);
+ parseCollateClause(tokens, newColumn);
+ parseColumnConstraint(tokens, newColumn);
+ }
+ tokens.canConsume(DdlTokenizer.COMMENT);
+ }
+
+ return newColumn;
+ }
+
+ private void parseGeneratedColumnSpecClause( DdlTokenStream tokens ) throws ParsingException {
+ // generated-column-spec
+ //
+ // [ GENERATED { ALWAYS | BY DEFAULT } AS IDENTITY [ ( START WITH IntegerConstant [ ,INCREMENT BY IntegerConstant] ) ] ] ]
+ if( tokens.canConsume("GENERATED") ) {
+ tokens.canConsume("ALWAYS");
+ tokens.canConsume("BY", "DEFAULT");
+ tokens.canConsume("AS", "IDENTITY");
+
+ if( tokens.canConsume("(", "START", "WITH") ) {
+ tokens.consume(); // integer constant
+ tokens.consume(',');
+ if( tokens.canConsume("INCREMENT", "BY")) {
+ tokens.consume(); // integer constant
+ }
+ tokens.consume(")");
+ }
+ }
+
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.jboss.dna.sequencer.ddl.StandardDdlParser#getDataTypeStartWords()
+ */
+ @Override
+ protected List<String> getCustomDataTypeStartWords() {
+ return DerbyDataTypes.CUSTOM_DATATYPE_START_WORDS;
+ }
+
+ class DerbyDataTypeParser extends DataTypeParser {
+
+ /**
+ *
+ * {@inheritDoc}
+ *
+ * @see org.jboss.dna.sequencer.ddl.datatype.DataTypeParser#isCustomDataType(org.jboss.dna.sequencer.ddl.DdlTokenStream)
+ */
+ @Override
+ protected boolean isCustomDataType(DdlTokenStream tokens)
+ throws ParsingException {
+ // Loop through the registered statement start string arrays and look for exact matches.
+
+ for( String[] stmts : derbyDataTypeStrings ) {
+ if( tokens.matches(stmts) ) return true;
+ }
+ return super.isCustomDataType(tokens);
+ }
+
+ /**
+ *
+ * {@inheritDoc}
+ *
+ * @see org.jboss.dna.sequencer.ddl.datatype.DataTypeParser#parseApproxNumericType(org.jboss.dna.sequencer.ddl.DdlTokenStream)
+ */
+ @Override
+ protected DataType parseApproxNumericType(DdlTokenStream tokens)
+ throws ParsingException {
+ return super.parseApproxNumericType(tokens);
+ }
+
+
+ /**
+ *
+ * {@inheritDoc}
+ *
+ * @see org.jboss.dna.sequencer.ddl.datatype.DataTypeParser#parseBitStringType(org.jboss.dna.sequencer.ddl.DdlTokenStream)
+ */
+ @Override
+ protected DataType parseBitStringType(DdlTokenStream tokens)
+ throws ParsingException {
+ return super.parseBitStringType(tokens);
+ }
+
+ /**
+ *
+ * {@inheritDoc}
+ *
+ * @see org.jboss.dna.sequencer.ddl.datatype.DataTypeParser#parseBracketedInteger(org.jboss.dna.sequencer.ddl.DdlTokenStream)
+ */
+ @Override
+ protected int parseBracketedInteger(DdlTokenStream tokens) {
+ return super.parseBracketedInteger(tokens);
+ }
+
+ /**
+ *
+ * {@inheritDoc}
+ *
+ * @see org.jboss.dna.sequencer.ddl.datatype.DataTypeParser#parseCharStringType(org.jboss.dna.sequencer.ddl.DdlTokenStream)
+ */
+ @Override
+ protected DataType parseCharStringType(DdlTokenStream tokens)
+ throws ParsingException {
+ DataType result = super.parseCharStringType(tokens);
+
+ tokens.canConsume("FOR", "BIT", "DATA");
+
+ return result;
+ }
+
+ /**
+ *
+ * {@inheritDoc}
+ *
+ * @see org.jboss.dna.sequencer.ddl.datatype.DataTypeParser#parseCustomType(org.jboss.dna.sequencer.ddl.DdlTokenStream)
+ */
+ @Override
+ protected DataType parseCustomType(DdlTokenStream tokens)
+ throws ParsingException {
+ DataType result = null;
+ String typeName = null;
+ int length = 0;
+
+ if( tokens.matches(DerbyDataTypes.DTYPE_BINARY_LARGE_OBJECT) || tokens.matches(DerbyDataTypes.DTYPE_CHARACTER_LARGE_OBJECT)) {
+ typeName = tokens.consume() + SPACE + tokens.consume() + SPACE + tokens.consume();
+ boolean isKMGLength = false;
+ String kmgValue = null;
+ if( tokens.canConsume('(')) {
+ String lengthValue = tokens.consume();
+ kmgValue = getKMG(lengthValue);
+
+ isKMGLength = isKMGInteger(lengthValue);
+
+ length = parseInteger(lengthValue);
+
+ tokens.canConsume(')');
+ }
+
+ result = new DataType(typeName, length);
+
+ result.setKMGLength(isKMGLength);
+ result.setKMGValue(kmgValue);
+ } else if( tokens.matches(DerbyDataTypes.DTYPE_CLOB) || tokens.matches(DerbyDataTypes.DTYPE_BLOB) ){
+ typeName = tokens.consume();
+ boolean isKMGLength = false;
+ String kmgValue = null;
+ if( tokens.canConsume('(')) {
+ String lengthValue = tokens.consume();
+ kmgValue = getKMG(lengthValue);
+
+ isKMGLength = isKMGInteger(lengthValue);
+
+ length = parseInteger(lengthValue);
+
+ tokens.canConsume(')');
+ }
+
+ result = new DataType(typeName, length);
+
+ result.setKMGLength(isKMGLength);
+ result.setKMGValue(kmgValue);
+ } else if( tokens.matches(DerbyDataTypes.DTYPE_BIGINT) ){
+ typeName = tokens.consume();
+ } else if( tokens.matches(DerbyDataTypes.DTYPE_LONG_VARCHAR_FBD) ){
+ typeName = tokens.consume() + SPACE + tokens.consume() + SPACE + tokens.consume() + SPACE + tokens.consume() + SPACE + tokens.consume();
+ } else if( tokens.matches(DerbyDataTypes.DTYPE_LONG_VARCHAR) ){
+ typeName = tokens.consume() + SPACE + tokens.consume();
+ } else if( tokens.matches(DerbyDataTypes.DTYPE_BIGINT) ){
+ typeName = tokens.consume();
+ } else if( tokens.matches(DerbyDataTypes.DTYPE_DOUBLE) ){
+ typeName = tokens.consume();
+ } else if( tokens.matches(DerbyDataTypes.DTYPE_XML) ){
+ typeName = tokens.consume();
+ }
+
+ if( result == null ) {
+ super.parseCustomType(tokens);
+ }
+ return result;
+ }
+
+ /**
+ *
+ * {@inheritDoc}
+ *
+ * @see org.jboss.dna.sequencer.ddl.datatype.DataTypeParser#parseDateTimeType(org.jboss.dna.sequencer.ddl.DdlTokenStream)
+ */
+ @Override
+ protected DataType parseDateTimeType(DdlTokenStream tokens)
+ throws ParsingException {
+ return super.parseDateTimeType(tokens);
+ }
+
+ /**
+ *
+ * {@inheritDoc}
+ *
+ * @see org.jboss.dna.sequencer.ddl.datatype.DataTypeParser#parseExactNumericType(org.jboss.dna.sequencer.ddl.DdlTokenStream)
+ */
+ @Override
+ protected DataType parseExactNumericType(DdlTokenStream tokens)
+ throws ParsingException {
+ return super.parseExactNumericType(tokens);
+ }
+
+ }
+
+
+
+}
Property changes on: branches/ddl_sequencer/extensions/dna-sequencer-ddl/src/main/java/org/jboss/dna/sequencer/ddl/dialect/DerbyDdlParser.java
___________________________________________________________________
Name: svn:mime-type
+ text/plain
Added: branches/ddl_sequencer/extensions/dna-sequencer-ddl/src/main/java/org/jboss/dna/sequencer/ddl/dialect/MySqlDdlParser.java
===================================================================
--- branches/ddl_sequencer/extensions/dna-sequencer-ddl/src/main/java/org/jboss/dna/sequencer/ddl/dialect/MySqlDdlParser.java (rev 0)
+++ branches/ddl_sequencer/extensions/dna-sequencer-ddl/src/main/java/org/jboss/dna/sequencer/ddl/dialect/MySqlDdlParser.java 2009-10-02 16:13:40 UTC (rev 1280)
@@ -0,0 +1,490 @@
+package org.jboss.dna.sequencer.ddl.dialect;
+
+import java.util.ArrayList;
+import java.util.List;
+
+
+import org.jboss.dna.common.text.ParsingException;
+import org.jboss.dna.sequencer.ddl.DdlTokenStream;
+import org.jboss.dna.sequencer.ddl.StandardDdlParser;
+import org.jboss.dna.sequencer.ddl.datatype.DataType;
+import org.jboss.dna.sequencer.ddl.datatype.DataTypeParser;
+import org.jboss.dna.sequencer.ddl.statement.Index;
+import org.jboss.dna.sequencer.ddl.statement.Statement;
+
+public class MySqlDdlParser extends StandardDdlParser {
+ /*
+ * ===========================================================================================================================
+ * Data Definition Statements
+ ALTER [DATABASE | EVENT | FUNCTION | SERVER | TABLE | VIEW]
+ CREATE [DATABASE | EVENT | FUNCTION | INDEX | PROCEDURE | SERVER | TABLE | TRIGGER | VIEW]
+ DROP [DATABASE | EVENT | FUNCTION | INDEX | PROCEDURE | SERVER | TABLE | TRIGGER | VIEW]
+ RENAME TABLE
+ */
+ private static final String[] STMT_CREATE_DATABASE = {"CREATE", "DATABASE"};
+ private static final String[] STMT_CREATE_EVENT = {"CREATE", "EVENT"};
+ private static final String[] STMT_CREATE_SERVER = {"CREATE", "SERVER"};
+ private static final String[] STMT_CREATE_FUNCTION = {"CREATE", "FUNCTION"};
+ private static final String[] STMT_CREATE_INDEX = {"CREATE", "INDEX"};
+ private static final String[] STMT_CREATE_UNIQUE_INDEX = {"CREATE", "UNIQUE", "INDEX"};
+ private static final String[] STMT_CREATE_PROCEDURE = {"CREATE", "PROCEDURE"};
+ private static final String[] STMT_CREATE_TRIGGER = {"CREATE", "TRIGGER"};
+
+ protected static final String[] DTYPE_TINYINT = {"TINYINT"}; // TINYINT[(M)] [UNSIGNED] [ZEROFILL]
+ protected static final String[] DTYPE_MEDIUMINT = {"MEDIUMINT"}; // MEDIUMINT[(M)] [UNSIGNED] [ZEROFILL]
+ protected static final String[] DTYPE_BIGINT = {"BIGINT"}; // BIGINT[(M)] [UNSIGNED] [ZEROFILL]
+ protected static final String[] DTYPE_FIXED = {"FIXED"};// FIXED[(M[,D])] [UNSIGNED] [ZEROFILL]
+ protected static final String[] DTYPE_BOOL = {"BOOL"};// BOOL
+ protected static final String[] DTYPE_BOOLEAN = {"BOOLEAN"};// BOOLEAN
+
+ protected static final String[] DTYPE_DOUBLE = {"DOUBLE"}; // DOUBLE[(M,D)] [UNSIGNED] [ZEROFILL]
+
+
+ /*
+ * ===========================================================================================================================
+ * DATYPES
+ * Numeric Types
+ -----------------------------------------------------------
+ NEW TYPE
+ -----------------------------------------------------------
+ ** BIT[(M)]
+ ** TINYINT[(M)] [UNSIGNED] [ZEROFILL]
+ ** BOOL, BOOLEAN
+ SMALLINT[(M)] [UNSIGNED] [ZEROFILL]
+ ** MEDIUMINT[(M)] [UNSIGNED] [ZEROFILL]
+ INT[(M)] [UNSIGNED] [ZEROFILL]
+ INTEGER[(M)] [UNSIGNED] [ZEROFILL]
+ ** BIGINT[(M)] [UNSIGNED] [ZEROFILL]
+ ** SERIAL is an alias for BIGINT UNSIGNED NOT NULL AUTO_INCREMENT UNIQUE.
+ FLOAT[(M,D)] [UNSIGNED] [ZEROFILL]
+ FLOAT(p) [UNSIGNED] [ZEROFILL]
+ ** DOUBLE[(M,D)] [UNSIGNED] [ZEROFILL]
+ DOUBLE PRECISION[(M,D)] [UNSIGNED] [ZEROFILL],
+ REAL[(M,D)] [UNSIGNED] [ZEROFILL]
+ DECIMAL[(M[,D])] [UNSIGNED] [ZEROFILL]
+ DEC[(M[,D])] [UNSIGNED] [ZEROFILL],
+ NUMERIC[(M[,D])] [UNSIGNED] [ZEROFILL],
+ ** FIXED[(M[,D])] [UNSIGNED] [ZEROFILL]
+
+ * Date and Time Types
+ *
+ DATE
+ DATETIME
+ TIMESTAMP
+ TIME
+ YEAR[2|4]
+
+ * String Types
+ *
+
+ [NATIONAL] CHAR[(M)] [CHARACTER SET charset_name] [COLLATE collation_name]
+ - CHAR is shorthand for CHARACTER. NATIONAL CHAR (or its equivalent short form, NCHAR) i
+ - The CHAR BYTE data type is an alias for the BINARY data type.
+ [NATIONAL] VARCHAR(M) [CHARACTER SET charset_name] [COLLATE collation_name]
+ - VARCHAR is shorthand for CHARACTER VARYING
+ BINARY(M)
+ VARBINARY(M)
+ TINYBLOB
+ TINYTEXT [CHARACTER SET charset_name] [COLLATE collation_name]
+ - A TEXT column with a maximum length of 255
+ BLOB[(M)]
+ - A BLOB column with a maximum length of 65,535
+ TEXT[(M)] [CHARACTER SET charset_name] [COLLATE collation_name]
+ - A TEXT column with a maximum length of 65,535
+ MEDIUMBLOB - maximum length of 16,777,215
+ MEDIUMTEXT [CHARACTER SET charset_name] [COLLATE collation_name]
+ - maximum length of 16,777,215
+ LONGBLOB - maximum length of 4,294,967,295
+ LONGTEXT [CHARACTER SET charset_name] [COLLATE collation_name]
+ - maximum length of 4,294,967,295
+ ENUM('value1','value2',...) [CHARACTER SET charset_name] [COLLATE collation_name]
+ - NULL or the special ''
+ - maximum of 65,535 distinct values
+ SET('value1','value2',...) [CHARACTER SET charset_name] [COLLATE collation_name]
+ - zero or more values
+ - maximum of 64 members
+
+ * ===========================================================================================================================
+ * CREATE TABLE
+
+ CREATE [TEMPORARY] TABLE [IF NOT EXISTS] tbl_name
+ (create_definition,...)
+ [table_options]
+ [partition_options]
+
+ Or:
+
+ CREATE [TEMPORARY] TABLE [IF NOT EXISTS] tbl_name
+ [(create_definition,...)]
+ [table_options]
+ [partition_options]
+ select_statement
+
+ Or:
+
+ CREATE [TEMPORARY] TABLE [IF NOT EXISTS] tbl_name
+ { LIKE old_tbl_name | (LIKE old_tbl_name) }
+
+ create_definition:
+ col_name column_definition
+ | [CONSTRAINT [symbol]] PRIMARY KEY [index_type] (index_col_name,...)
+ [index_option] ...
+ | {INDEX|KEY} [index_name] [index_type] (index_col_name,...)
+ [index_option] ...
+ | [CONSTRAINT [symbol]] UNIQUE [INDEX|KEY]
+ [index_name] [index_type] (index_col_name,...)
+ [index_option] ...
+ | {FULLTEXT|SPATIAL} [INDEX|KEY] [index_name] (index_col_name,...)
+ [index_option] ...
+ | [CONSTRAINT [symbol]] FOREIGN KEY
+ [index_name] (index_col_name,...) reference_definition
+ | CHECK (expr)
+
+ column_definition:
+ data_type [NOT NULL | NULL] [DEFAULT default_value]
+ [AUTO_INCREMENT] [UNIQUE [KEY] | [PRIMARY] KEY]
+ [COMMENT 'string']
+ [COLUMN_FORMAT {FIXED|DYNAMIC|DEFAULT}]
+ [STORAGE {DISK|MEMORY|DEFAULT}]
+ [reference_definition]
+
+ data_type:
+ BIT[(length)]
+ | TINYINT[(length)] [UNSIGNED] [ZEROFILL]
+ | SMALLINT[(length)] [UNSIGNED] [ZEROFILL]
+ | MEDIUMINT[(length)] [UNSIGNED] [ZEROFILL]
+ | INT[(length)] [UNSIGNED] [ZEROFILL]
+ | INTEGER[(length)] [UNSIGNED] [ZEROFILL]
+ | BIGINT[(length)] [UNSIGNED] [ZEROFILL]
+ | REAL[(length,decimals)] [UNSIGNED] [ZEROFILL]
+ | DOUBLE[(length,decimals)] [UNSIGNED] [ZEROFILL]
+ | FLOAT[(length,decimals)] [UNSIGNED] [ZEROFILL]
+ | DECIMAL[(length[,decimals])] [UNSIGNED] [ZEROFILL]
+ | NUMERIC[(length[,decimals])] [UNSIGNED] [ZEROFILL]
+ | DATE
+ | TIME
+ | TIMESTAMP
+ | DATETIME
+ | YEAR
+ | CHAR[(length)]
+ [CHARACTER SET charset_name] [COLLATE collation_name]
+ | VARCHAR(length)
+ [CHARACTER SET charset_name] [COLLATE collation_name]
+ | BINARY[(length)]
+ | VARBINARY(length)
+ | TINYBLOB
+ | BLOB
+ | MEDIUMBLOB
+ | LONGBLOB
+ | TINYTEXT [BINARY]
+ [CHARACTER SET charset_name] [COLLATE collation_name]
+ | TEXT [BINARY]
+ [CHARACTER SET charset_name] [COLLATE collation_name]
+ | MEDIUMTEXT [BINARY]
+ [CHARACTER SET charset_name] [COLLATE collation_name]
+ | LONGTEXT [BINARY]
+ [CHARACTER SET charset_name] [COLLATE collation_name]
+ | ENUM(value1,value2,value3,...)
+ [CHARACTER SET charset_name] [COLLATE collation_name]
+ | SET(value1,value2,value3,...)
+ [CHARACTER SET charset_name] [COLLATE collation_name]
+ | spatial_type
+
+ index_col_name:
+ col_name [(length)] [ASC | DESC]
+
+ index_type:
+ USING {BTREE | HASH | RTREE}
+
+ index_option:
+ KEY_BLOCK_SIZE [=] value
+ | index_type
+ | WITH PARSER parser_name
+
+ reference_definition:
+ REFERENCES tbl_name (index_col_name,...)
+ [MATCH FULL | MATCH PARTIAL | MATCH SIMPLE]
+ [ON DELETE reference_option]
+ [ON UPDATE reference_option]
+
+ reference_option:
+ RESTRICT | CASCADE | SET NULL | NO ACTION
+
+ table_options:
+ table_option [[,] table_option] ...
+
+ table_option:
+ ENGINE [=] engine_name
+ | AUTO_INCREMENT [=] value
+ | AVG_ROW_LENGTH [=] value
+ | [DEFAULT] CHARACTER SET [=] charset_name
+ | CHECKSUM [=] {0 | 1}
+ | [DEFAULT] COLLATE [=] collation_name
+ | COMMENT [=] 'string'
+ | CONNECTION [=] 'connect_string'
+ | DATA DIRECTORY [=] 'absolute path to directory'
+ | DELAY_KEY_WRITE [=] {0 | 1}
+ | INDEX DIRECTORY [=] 'absolute path to directory'
+ | INSERT_METHOD [=] { NO | FIRST | LAST }
+ | KEY_BLOCK_SIZE [=] value
+ | MAX_ROWS [=] value
+ | MIN_ROWS [=] value
+ | PACK_KEYS [=] {0 | 1 | DEFAULT}
+ | PASSWORD [=] 'string'
+ | ROW_FORMAT [=] {DEFAULT|DYNAMIC|FIXED|COMPRESSED|REDUNDANT|COMPACT}
+ | TABLESPACE tablespace_name [STORAGE {DISK|MEMORY|DEFAULT}]
+ | UNION [=] (tbl_name[,tbl_name]...)
+
+ partition_options:
+ PARTITION BY
+ { [LINEAR] HASH(expr)
+ | [LINEAR] KEY(column_list)
+ | RANGE(expr)
+ | LIST(expr) }
+ [PARTITIONS num]
+ [SUBPARTITION BY
+ { [LINEAR] HASH(expr)
+ | [LINEAR] KEY(column_list) }
+ [SUBPARTITIONS num]
+ ]
+ [(partition_definition [, partition_definition] ...)]
+
+ partition_definition:
+ PARTITION partition_name
+ [VALUES {LESS THAN {(expr) | MAXVALUE} | IN (value_list)}]
+ [[STORAGE] ENGINE [=] engine_name]
+ [COMMENT [=] 'comment_text' ]
+ [DATA DIRECTORY [=] 'data_dir']
+ [INDEX DIRECTORY [=] 'index_dir']
+ [MAX_ROWS [=] max_number_of_rows]
+ [MIN_ROWS [=] min_number_of_rows]
+ [TABLESPACE [=] tablespace_name]
+ [NODEGROUP [=] node_group_id]
+ [(subpartition_definition [, subpartition_definition] ...)]
+
+ subpartition_definition:
+ SUBPARTITION logical_name
+ [[STORAGE] ENGINE [=] engine_name]
+ [COMMENT [=] 'comment_text' ]
+ [DATA DIRECTORY [=] 'data_dir']
+ [INDEX DIRECTORY [=] 'index_dir']
+ [MAX_ROWS [=] max_number_of_rows]
+ [MIN_ROWS [=] min_number_of_rows]
+ [TABLESPACE [=] tablespace_name]
+ [NODEGROUP [=] node_group_id]
+
+ select_statement:
+ [IGNORE | REPLACE] [AS] SELECT ... (Some legal select statement)
+
+
+ * ===========================================================================================================================
+ */
+ private static final String TERMINATOR = DEFAULT_TERMINATOR;
+
+ public MySqlDdlParser() {
+ initialize();
+ }
+
+
+ private void initialize() {
+ setDatatypeParser(new MySqlDataTypeParser());
+
+ registerStatementStartPhrase(STMT_CREATE_FUNCTION);
+ registerStatementStartPhrase(STMT_CREATE_INDEX);
+ registerStatementStartPhrase(STMT_CREATE_UNIQUE_INDEX);
+ registerStatementStartPhrase(STMT_CREATE_PROCEDURE);
+ registerStatementStartPhrase(STMT_CREATE_SERVER);
+ registerStatementStartPhrase(STMT_CREATE_TRIGGER);
+ registerStatementStartPhrase(STMT_CREATE_DATABASE);
+ registerStatementStartPhrase(STMT_CREATE_EVENT);
+
+ setDoUseTerminator(true);
+
+ setTerminator(TERMINATOR);
+ }
+ // ===========================================================================================================================
+ // ===========================================================================================================================
+ @Override
+ protected Statement parseCreateStatement(DdlTokenStream tokens, boolean inSchema)
+ throws ParsingException {
+ Statement result = null;
+
+
+ if( tokens.matches(STMT_CREATE_INDEX)
+ || tokens.matches(STMT_CREATE_UNIQUE_INDEX) ) {
+ result = parseCreateIndex(tokens);
+ } else if( tokens.matches(STMT_CREATE_FUNCTION) ) {
+ result = parseIgnorableStatement(tokens, "CREATE FUNCTION");
+ } else if( tokens.matches(STMT_CREATE_PROCEDURE) ) {
+ result = parseIgnorableStatement(tokens, "CREATE PROCEDURE");
+ } else if( tokens.matches(STMT_CREATE_EVENT) ) {
+ result = parseIgnorableStatement(tokens, "CREATE EVENT");
+ } else if( tokens.matches(STMT_CREATE_SERVER) ) {
+ result = parseIgnorableStatement(tokens, "CREATE SERVER");
+ } else if( tokens.matches(STMT_CREATE_TRIGGER) ) {
+ result = parseIgnorableStatement(tokens, "CREATE TRIGGER");
+ }
+
+ if( result == null ) {
+ result = super.parseCreateStatement(tokens, inSchema);
+ }
+
+ return result;
+ }
+
+ protected Statement parseCreateIndex( DdlTokenStream tokens ) throws ParsingException {
+ // CREATE [UNIQUE] INDEX index-Name
+ // ON table-Name ( Simple-column-Name [ ASC | DESC ] [ , Simple-column-Name [ ASC | DESC ]] * )
+ tokens.consume(); // CREATE
+ boolean isUnique = tokens.canConsume("UNIQUE");
+ tokens.consume("INDEX");
+ String indexName = consumeIdentifier(tokens);
+ tokens.consume("ON");
+ String tableName = consumeIdentifier(tokens);
+
+ //System.out.println(" >> PARSING Create INDEX >> Name = " + indexName + " For TABLE = " + tableName);
+
+ List<String> columnNameList = new ArrayList<String>();
+ try {
+ if( tokens.matches('(')) {
+ tokens.consume();
+ columnNameList = parseColumnNameList(tokens);
+ tokens.consume(')');
+ }
+ } catch (ParsingException e) {
+ // Give up on parsing, probably a nested function (i.e. banned (lower(banned_name));
+ parseUntilTerminator(tokens);
+ }
+ Index newIndex = new Index(indexName, tableName, columnNameList);
+ newIndex.setUnique(isUnique);
+
+ consumeTerminator(tokens);
+
+ return newIndex;
+ }
+
+
+
+ // ===========================================================================================================================
+ // ===========================================================================================================================
+
+
+ // ===========================================================================================================================
+ // ===========================================================================================================================
+ class MySqlDataTypeParser extends DataTypeParser {
+
+ // NOTE THAT MYSQL allows "UNSIGNED" and "ZEROFILL" as options AFTER the datatype definition
+ // Need to override and do a CHECK for and CONSUME them.
+
+
+
+ @Override
+ protected DataType parseApproxNumericType(DdlTokenStream tokens)
+ throws ParsingException {
+ return super.parseApproxNumericType(tokens);
+ }
+
+ @Override
+ protected DataType parseBitStringType(DdlTokenStream tokens)
+ throws ParsingException {
+ return super.parseBitStringType(tokens);
+ }
+
+ @Override
+ protected int parseBracketedInteger(DdlTokenStream tokens) {
+ return super.parseBracketedInteger(tokens);
+ }
+
+ @Override
+ protected DataType parseCharStringType(DdlTokenStream tokens)
+ throws ParsingException {
+ DataType result = super.parseCharStringType(tokens);
+
+ tokens.canConsume("FOR", "BIT", "DATA");
+
+ return result;
+ }
+
+ @Override
+ protected DataType parseCustomType(DdlTokenStream tokens)
+ throws ParsingException {
+ DataType result = null;
+ String typeName = null;
+ int length = 0;
+
+// if( tokens.matches(DTYPE_BINARY_LARGE_OBJECT) || tokens.matches(DTYPE_CHARACTER_LARGE_OBJECT)) {
+// typeName = tokens.consume() + SPACE + tokens.consume() + SPACE + tokens.consume();
+// boolean isKMGLength = false;
+// String kmgValue = null;
+// if( tokens.canConsume('(')) {
+// String lengthValue = tokens.consume();
+// kmgValue = getKMG(lengthValue);
+//
+// isKMGLength = isKMGInteger(lengthValue);
+//
+// length = parseInteger(lengthValue);
+//
+// tokens.canConsume(')');
+// }
+//
+// result = new DataType(typeName, length);
+//
+// result.setKMGLength(isKMGLength);
+// result.setKMGValue(kmgValue);
+// } else if( tokens.matches(DTYPE_CLOB) || tokens.matches(DTYPE_BLOB) ){
+// typeName = tokens.consume();
+// boolean isKMGLength = false;
+// String kmgValue = null;
+// if( tokens.canConsume('(')) {
+// String lengthValue = tokens.consume();
+// kmgValue = getKMG(lengthValue);
+//
+// isKMGLength = isKMGInteger(lengthValue);
+//
+// length = parseInteger(lengthValue);
+//
+// tokens.canConsume(')');
+// }
+//
+// result = new DataType(typeName, length);
+//
+// result.setKMGLength(isKMGLength);
+// result.setKMGValue(kmgValue);
+// } else if( tokens.matches(DTYPE_BIGINT) ){
+// typeName = tokens.consume();
+// } else if( tokens.matches(DTYPE_LONG_VARCHAR_FBD) ){
+// typeName = tokens.consume() + SPACE + tokens.consume() + SPACE + tokens.consume() + SPACE + tokens.consume() + SPACE + tokens.consume();
+// } else if( tokens.matches(DTYPE_LONG_VARCHAR) ){
+// typeName = tokens.consume() + SPACE + tokens.consume();
+// } else if( tokens.matches(DTYPE_BIGINT) ){
+// typeName = tokens.consume();
+// } else if( tokens.matches(DTYPE_DOUBLE) ){
+// typeName = tokens.consume();
+// } else if( tokens.matches(DTYPE_XML) ){
+// typeName = tokens.consume();
+// }
+
+ if( result == null ) {
+ super.parseCustomType(tokens);
+ }
+ return result;
+ }
+
+ @Override
+ protected DataType parseDateTimeType(DdlTokenStream tokens)
+ throws ParsingException {
+ return super.parseDateTimeType(tokens);
+ }
+
+ @Override
+ protected DataType parseExactNumericType(DdlTokenStream tokens)
+ throws ParsingException {
+ return super.parseExactNumericType(tokens);
+ }
+
+ }
+
+
+
+
+}
Property changes on: branches/ddl_sequencer/extensions/dna-sequencer-ddl/src/main/java/org/jboss/dna/sequencer/ddl/dialect/MySqlDdlParser.java
___________________________________________________________________
Name: svn:mime-type
+ text/plain
Added: branches/ddl_sequencer/extensions/dna-sequencer-ddl/src/main/java/org/jboss/dna/sequencer/ddl/dialect/PostgresDdlParser.java
===================================================================
--- branches/ddl_sequencer/extensions/dna-sequencer-ddl/src/main/java/org/jboss/dna/sequencer/ddl/dialect/PostgresDdlParser.java (rev 0)
+++ branches/ddl_sequencer/extensions/dna-sequencer-ddl/src/main/java/org/jboss/dna/sequencer/ddl/dialect/PostgresDdlParser.java 2009-10-02 16:13:40 UTC (rev 1280)
@@ -0,0 +1,88 @@
+package org.jboss.dna.sequencer.ddl.dialect;
+
+import org.jboss.dna.sequencer.ddl.StandardDdlParser;
+
+public class PostgresDdlParser extends StandardDdlParser {
+ private static final String[] COMMENT_ON = {"COMMENT", "ON"};
+
+ // SQL COMMANDS FOUND @ http://www.postgresql.org/docs/8.4/static/sql-commands.html
+
+// bigint 8 bytes large-range integer -9223372036854775808 to 9223372036854775807
+// serial 4 bytes autoincrementing integer 1 to 2147483647
+// bigserial 8 bytes large autoincrementing integer 1 to 9223372036854775807
+//
+// money 8 bytes currency amount -92233720368547758.08 to +92233720368547758.07
+// text variable unlimited length
+// bytea 1 or 4 bytes plus the actual binary string variable-length binary string
+//
+// timestamp [ (p) ] [ without time zone ] 8 bytes both date and time (no time zone) 4713 BC 294276 AD 1 microsecond / 14 digits
+// timestamp [ (p) ] with time zone 8 bytes both date and time, with time zone 4713 BC 294276 AD 1 microsecond / 14 digits
+// date 4 bytes date (no time of day) 4713 BC 5874897 AD 1 day
+// time [ (p) ] [ without time zone ] 8 bytes time of day (no date) 00:00:00 24:00:00 1 microsecond / 14 digits
+// time [ (p) ] with time zone 12 bytes times of day only, with time zone 00:00:00+1459 24:00:00-1459 1 microsecond / 14 digits
+// interval [ fields ] [ (p) ] 12 bytes time interval -178000000 years 178000000 years 1 microsecond / 14 digits
+// boolean
+//
+// YEAR
+// MONTH
+// DAY
+// HOUR
+// MINUTE
+// SECOND
+// YEAR TO MONTH
+// DAY TO HOUR
+// DAY TO MINUTE
+// DAY TO SECOND
+// HOUR TO MINUTE
+// HOUR TO SECOND
+// MINUTE TO SECOND
+//
+// CREATE TYPE happiness AS ENUM ('happy', 'very happy', 'ecstatic');
+// CREATE TABLE holidays (
+// num_weeks integer,
+// happiness happiness
+// );
+//
+// cidr 7 or 19 bytes IPv4 and IPv6 networks
+// inet 7 or 19 bytes IPv4 and IPv6 hosts and networks
+// macaddr 6 bytes MAC addresses
+// uuid
+// xml
+// CREATE TABLE sal_emp (
+// name text,
+// pay_by_quarter integer[],
+// schedule text[][]
+// );
+// CREATE TABLE tictactoe (
+// squares integer[3][3]
+// );
+// pay_by_quarter integer ARRAY[4],
+//
+// Or, if no array size is to be specified:
+//
+// pay_by_quarter integer ARRAY,
+
+
+ private static final String TERMINATOR = "GO";
+
+ public PostgresDdlParser() {
+ initialize();
+ }
+
+
+ private void initialize() {
+ registerStatementStartPhrase(COMMENT_ON);
+ setTerminator(TERMINATOR);
+ }
+ // ===========================================================================================================================
+ // ===========================================================================================================================
+
+
+ // ===========================================================================================================================
+ // ===========================================================================================================================
+
+
+ // ===========================================================================================================================
+ // ===========================================================================================================================
+
+}
Property changes on: branches/ddl_sequencer/extensions/dna-sequencer-ddl/src/main/java/org/jboss/dna/sequencer/ddl/dialect/PostgresDdlParser.java
___________________________________________________________________
Name: svn:mime-type
+ text/plain
Added: branches/ddl_sequencer/extensions/dna-sequencer-ddl/src/main/java/org/jboss/dna/sequencer/ddl/dialect/SqlServerDdlParser.java
===================================================================
--- branches/ddl_sequencer/extensions/dna-sequencer-ddl/src/main/java/org/jboss/dna/sequencer/ddl/dialect/SqlServerDdlParser.java (rev 0)
+++ branches/ddl_sequencer/extensions/dna-sequencer-ddl/src/main/java/org/jboss/dna/sequencer/ddl/dialect/SqlServerDdlParser.java 2009-10-02 16:13:40 UTC (rev 1280)
@@ -0,0 +1,30 @@
+package org.jboss.dna.sequencer.ddl.dialect;
+
+import org.jboss.dna.sequencer.ddl.StandardDdlParser;
+
+public class SqlServerDdlParser extends StandardDdlParser {
+ private static final String[] COMMENT_ON = {"COMMENT", "ON"};
+
+ private static final String TERMINATOR = "GO";
+
+ public SqlServerDdlParser() {
+ initialize();
+ }
+
+
+ private void initialize() {
+ registerStatementStartPhrase(COMMENT_ON);
+ setTerminator(TERMINATOR);
+ }
+ // ===========================================================================================================================
+ // ===========================================================================================================================
+
+
+ // ===========================================================================================================================
+ // ===========================================================================================================================
+
+
+ // ===========================================================================================================================
+ // ===========================================================================================================================
+
+}
Property changes on: branches/ddl_sequencer/extensions/dna-sequencer-ddl/src/main/java/org/jboss/dna/sequencer/ddl/dialect/SqlServerDdlParser.java
___________________________________________________________________
Name: svn:mime-type
+ text/plain
Added: branches/ddl_sequencer/extensions/dna-sequencer-ddl/src/main/java/org/jboss/dna/sequencer/ddl/dialect/SybaseDdlParser.java
===================================================================
--- branches/ddl_sequencer/extensions/dna-sequencer-ddl/src/main/java/org/jboss/dna/sequencer/ddl/dialect/SybaseDdlParser.java (rev 0)
+++ branches/ddl_sequencer/extensions/dna-sequencer-ddl/src/main/java/org/jboss/dna/sequencer/ddl/dialect/SybaseDdlParser.java 2009-10-02 16:13:40 UTC (rev 1280)
@@ -0,0 +1,127 @@
+package org.jboss.dna.sequencer.ddl.dialect;
+
+import org.jboss.dna.sequencer.ddl.StandardDdlParser;
+
+public class SybaseDdlParser extends StandardDdlParser {
+ private static final String[] COMMENT_ON = {"COMMENT", "ON"};
+
+ /*
+ *
+ *
+ * Character
+ CHAR [ ( max-length ) ]
+ CHARACTER [ ( max-length ) ]
+ CHARACTER VARYING [ ( max-length ) ]
+ VARCHAR [ ( max-length ) ]
+ UNIQUEIDENTIFIERSTR
+ * Numeric
+ [ UNSIGNED ] BIGINT
+ [ UNSIGNED ] { INT | INTEGER }
+ SMALLINT
+ TINYINT
+ DECIMAL [ ( precision [ , scale ] ) ]
+ NUMERIC [ ( precision [ , scale ] ) ]
+ DOUBLE
+ FLOAT [ ( precision ) ]
+ REAL
+ * Binary
+ BINARY [ ( length ) ]
+ VARBINARY [ ( max-length ) ]
+ UNIQUEIDENTIFIER
+ * Bit
+ BIT
+ * Date/Time
+ DATE
+ DATETIME
+ SMALLDATETIME
+ TIME
+ TIMESTAMP
+
+
+ * ===========================================================================================================================
+ * Data Definition Statements
+ ALLOCATE DESCRIPTOR
+ ALTER [DATABASE | DBSPACE | DOMAIN | EVENT | FUNCTION | INDEX | (LOGIN POLICY) | PROCEDURE | SERVER | SERVICE | TABLE | USER | VIEW]
+ BACKUP
+ BEGIN PARALLEL IQ … END PARALLEL IQ statement
+ BEGIN TRAN[SACTION] [ transaction-name ]
+ CHECKPOINT
+ COMMENT ON
+ COMMIT [ WORK ]
+ CONFIGURE
+ CREATE [DATABASE | DBSPACE | DOMAIN | EVENT | (EXISTING TABLE) | EXTERNLOGIN | FUNCTION | INDEX | (JOIN INDEX)
+ | (LOGIN POLICY) | MESSAGE | PROCEDURE | SCHEMA | SERVER | SERVICE | TABLE | USER | VARIABLE | VIEW]
+ DEALLOCATE DESCRIPTOR
+ DECLARE LOCAL TEMPORARY TABLE
+ DELETE
+ DESCRIBE
+ DROP [CONNECTION | DATABASE | DBSPACE | DOMAIN | EVENT | EXTERNALLOGIN | FUNCTION | INDEX | (JOIN INDEX) | (LOGIN POLICY)
+ | MESSAGE | PROCEDURE | SERVER | STATEMENT | TABLE | TRIGGER | USER | VARIABLE | VIEW]
+ EXEC[UTE]
+ EXIT
+ FORWARD TO
+ GET DESCRIPTOR
+ GRANT
+ INSERT
+ INSTALL JAVA
+ IQ UTILITIES
+ LOAD TABLE
+ LOCK TABLE
+ OUTPUT TO
+ PARAMETERS
+ READ
+ RELEASE SAVEPOINT
+ REMOVE JAVA
+ RESTORE DATABASE
+ REVOKE
+ ROLLBACK [WORK]
+ ROLLBACK TO SAVEPOINT
+ SAVEPOINT
+ SET [CONNECTION | DESCRIPTION | OPTION | SQLCA]
+ SIGNAL
+ START [DATABASE | ENGINE | JAVA]
+ STOP [DATABASE | ENGINE | JAVA]
+ SYNCHRONIZE JOIN INDEX
+ TRIGGER EVENT
+ TRUNCATE TABLE
+ UPDATE
+ WAITFOR
+
+
+ * ===========================================================================================================================
+ * CREATE TABLE
+
+
+
+
+
+
+
+ */
+
+
+
+
+ private static final String TERMINATOR = "go";
+
+ public SybaseDdlParser() {
+ initialize();
+ }
+
+
+ private void initialize() {
+ registerStatementStartPhrase(COMMENT_ON);
+ setTerminator(TERMINATOR);
+ }
+ // ===========================================================================================================================
+ // ===========================================================================================================================
+
+
+ // ===========================================================================================================================
+ // ===========================================================================================================================
+
+
+ // ===========================================================================================================================
+ // ===========================================================================================================================
+
+}
Property changes on: branches/ddl_sequencer/extensions/dna-sequencer-ddl/src/main/java/org/jboss/dna/sequencer/ddl/dialect/SybaseDdlParser.java
___________________________________________________________________
Name: svn:mime-type
+ text/plain
Added: branches/ddl_sequencer/extensions/dna-sequencer-ddl/src/main/java/org/jboss/dna/sequencer/ddl/dialect/derby/DerbyDdlConstants.java
===================================================================
--- branches/ddl_sequencer/extensions/dna-sequencer-ddl/src/main/java/org/jboss/dna/sequencer/ddl/dialect/derby/DerbyDdlConstants.java (rev 0)
+++ branches/ddl_sequencer/extensions/dna-sequencer-ddl/src/main/java/org/jboss/dna/sequencer/ddl/dialect/derby/DerbyDdlConstants.java 2009-10-02 16:13:40 UTC (rev 1280)
@@ -0,0 +1,115 @@
+/*
+ * JBoss DNA (http://www.jboss.org/dna)
+ * 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.
+ * See the AUTHORS.txt file in the distribution for a full listing of
+ * individual contributors.
+ *
+ * JBoss DNA is free software. Unless otherwise indicated, all code in JBoss DNA
+ * is licensed to you 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.
+ *
+ * JBoss DNA 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 software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.dna.sequencer.ddl.dialect.derby;
+
+import java.util.Arrays;
+import java.util.List;
+
+import org.jboss.dna.sequencer.ddl.DdlConstants;
+
+/**
+ * @author blafond
+ *
+ */
+public interface DerbyDdlConstants extends DdlConstants {
+ public static final String[] CUSTOM_KEYWORDS = {
+ "TRIGGER", "SYNOMYM", "LOCK", "ISOLATION", "SQLID", INDEX, "RENAME", "DECLARE"
+ };
+
+ interface DerbyStatementStartPhrases {
+
+ static final String[][] ALTER_PHRASES = {
+ };
+
+ static final String[] STMT_CREATE_FUNCTION = {CREATE, "FUNCTION"};
+ static final String[] STMT_CREATE_INDEX = {CREATE, "INDEX"};
+ static final String[] STMT_CREATE_UNIQUE_INDEX = {CREATE, "UNIQUE", INDEX};
+ static final String[] STMT_CREATE_PROCEDURE = {CREATE, "PROCEDURE"};
+ static final String[] STMT_CREATE_ROLE = {CREATE, "ROLE"};
+ static final String[] STMT_CREATE_SYNONYM = {CREATE, "SYNONYM"};
+ static final String[] STMT_CREATE_TRIGGER = {CREATE, "TRIGGER"};
+
+ static final String[][] CREATE_PHRASES = {
+ STMT_CREATE_FUNCTION, STMT_CREATE_INDEX, STMT_CREATE_UNIQUE_INDEX, STMT_CREATE_PROCEDURE,
+ STMT_CREATE_ROLE, STMT_CREATE_SYNONYM, STMT_CREATE_TRIGGER
+ };
+
+ static final String[] STMT_DECLARE_GLOBAL_TEMP_TABLE = {"DECLARE", "GLOBAL", "TEMPORARY", "TABLE"};
+ static final String[] STMT_DROP_FUNCTION = {DROP, "FUNCTION"};
+ static final String[] STMT_DROP_INDEX = {DROP, "INDEX"};
+ static final String[] STMT_DROP_PROCEDURE = {DROP, "PROCEDURE"};
+ static final String[] STMT_DROP_ROLE = {DROP, "ROLE"};
+ static final String[] STMT_DROP_SYNONYM = {DROP, "SYNONYM"};
+ static final String[] STMT_DROP_TRIGGER = {DROP, "TRIGGER"};
+
+ static final String[][] DROP_PHRASES = {
+ STMT_DROP_FUNCTION, STMT_DROP_INDEX, STMT_DROP_PROCEDURE, STMT_DROP_ROLE, STMT_DROP_SYNONYM, STMT_DROP_TRIGGER
+ };
+
+ static final String[] STMT_GRANT = {"GRANT"};
+ static final String[] STMT_LOCK_TABLE = {"LOCK", TABLE};
+ static final String[] STMT_RENAME_TABLE = {"RENAME", TABLE};
+ static final String[] STMT_RENAME_INDEX = {"RENAME", INDEX};
+
+
+ static final String[] STMT_SET_ISOLATION = {SET, "ISOLATION"};
+ static final String[] STMT_SET_CURRENT_ISOLATION = {SET, "CURRENT", "ISOLATION"};
+ static final String[] STMT_SET_ROLE = {SET, "ROLE"};
+ static final String[] STMT_SET_SCHEMA = {SET, "SCHEMA"};
+ static final String[] STMT_SET_CURRENT_SCHEMA = {SET, "CURRENT", SCHEMA};
+ static final String[] STMT_SET_CURRENT_SQLID = {SET, "CURRENT", "SQLID"};
+
+ static final String[][] SET_PHRASES = {
+ STMT_SET_ISOLATION, STMT_SET_CURRENT_ISOLATION, STMT_SET_ROLE, STMT_SET_SCHEMA, STMT_SET_CURRENT_SCHEMA,
+ STMT_SET_CURRENT_SQLID
+ };
+
+ static final String[][] MISC_PHRASES = { STMT_LOCK_TABLE, STMT_RENAME_TABLE, STMT_RENAME_INDEX, STMT_GRANT,
+ STMT_DECLARE_GLOBAL_TEMP_TABLE
+ };
+ }
+ interface DerbyDataTypes {
+ static final String[] DTYPE_BIGINT = {"BIGINT"};
+ static final String[] DTYPE_LONG_VARCHAR = {"LONG", "VARCHAR"};
+ static final String[] DTYPE_LONG_VARCHAR_FBD = {"LONG", "VARCHAR", "FOR", "BIT", "DATA"};
+
+ static final String[] DTYPE_DOUBLE = {"DOUBLE"};
+ static final String[] DTYPE_XML = {"XML"};
+ static final String[] DTYPE_CLOB = {"CLOB"}; // CLOB [ ( length [{K |M |G }] ) ]
+ static final String[] DTYPE_CHARACTER_LARGE_OBJECT = {"CHARACTER", "LARGE", "OBJECT"}; // [ ( length [{K |M |G }] ) ]
+ static final String[] DTYPE_BLOB = {"BLOB"}; // BLOB [ ( length [{K |M |G }] ) ]
+ static final String[] DTYPE_BINARY_LARGE_OBJECT = {"BINARY", "LARGE", "OBJECT"}; // [ ( length [{K |M |G }] ) ]
+
+ static final List<String[]> CUSTOM_DATATYPE_START_PHRASES =
+ Arrays.asList(new String[][] {
+ DTYPE_BIGINT, DTYPE_LONG_VARCHAR, DTYPE_LONG_VARCHAR_FBD, DTYPE_DOUBLE, DTYPE_XML,
+ DTYPE_CLOB, DTYPE_CHARACTER_LARGE_OBJECT, DTYPE_BLOB, DTYPE_BINARY_LARGE_OBJECT
+ });
+
+ static final List<String> CUSTOM_DATATYPE_START_WORDS =
+ Arrays.asList(new String[] {"BIGINT", "LONG", "DOUBLE",
+ "XML", "CLOB", "CHARACTER", "BLOB", "BINARY"
+ });
+ }
+}
Property changes on: branches/ddl_sequencer/extensions/dna-sequencer-ddl/src/main/java/org/jboss/dna/sequencer/ddl/dialect/derby/DerbyDdlConstants.java
___________________________________________________________________
Name: svn:mime-type
+ text/plain
Added: branches/ddl_sequencer/extensions/dna-sequencer-ddl/src/main/java/org/jboss/dna/sequencer/ddl/dialect/oracle/OracleDdlConstants.java
===================================================================
--- branches/ddl_sequencer/extensions/dna-sequencer-ddl/src/main/java/org/jboss/dna/sequencer/ddl/dialect/oracle/OracleDdlConstants.java (rev 0)
+++ branches/ddl_sequencer/extensions/dna-sequencer-ddl/src/main/java/org/jboss/dna/sequencer/ddl/dialect/oracle/OracleDdlConstants.java 2009-10-02 16:13:40 UTC (rev 1280)
@@ -0,0 +1,250 @@
+/*
+ * JBoss DNA (http://www.jboss.org/dna)
+ * 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.
+ * See the AUTHORS.txt file in the distribution for a full listing of
+ * individual contributors.
+ *
+ * JBoss DNA is free software. Unless otherwise indicated, all code in JBoss DNA
+ * is licensed to you 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.
+ *
+ * JBoss DNA 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 software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.dna.sequencer.ddl.dialect.oracle;
+
+import java.util.Arrays;
+import java.util.List;
+
+import org.jboss.dna.sequencer.ddl.DdlConstants;
+
+/**
+ * Oracle-specific constants including key words and statement start phrases.
+ *
+ * @author blafond
+ *
+ */
+public interface OracleDdlConstants extends DdlConstants {
+
+ public static final String[] CUSTOM_KEYWORDS = {
+ "ANALYZE", "ASSOCIATE", "TRUNCATE", "MATERIALIZED", "SAVEPOINT", "PURGE", "LOCK", "TRIGGER", "EXPLAIN", "PLAN", "DIMENSION",
+ "DIRECTORY", "DATABASE", "CONTROLFILE", "DISKGROUP", "INDEXTYPE", "SYNONYM", "SEQUENCE", "LIBRARY", "CLUSTER", "OUTLINE",
+ "PACKAGE", "SPFILE", "PFILE", "AUDIT", "COMMIT", "PURGE", "MERGE", "RENAME", "FLASHBACK", "NOAUDIT", "DISASSOCIATE",
+ "NESTED", "REVOKE", "COMMENT", INDEX
+ };
+
+ interface OracleStatementStartPhrases {
+ static final String[] STMT_ALTER_CLUSTER = {ALTER, "CLUSTER"};
+ static final String[] STMT_ALTER_DATABASE = {ALTER, "DATABASE"};
+ static final String[] STMT_ALTER_DIMENSION = {ALTER, "DIMENSION"};
+ static final String[] STMT_ALTER_DISKGROUP = {ALTER, "DISKGROUP"};
+ static final String[] STMT_ALTER_FUNCTION = {ALTER, "FUNCTION"};
+ static final String[] STMT_ALTER_INDEX = {ALTER, INDEX};
+ static final String[] STMT_ALTER_INDEXTYPE = {ALTER, "INDEXTYPE"};
+ static final String[] STMT_ALTER_JAVA = {ALTER, "JAVA"};
+ static final String[] STMT_ALTER_MATERIALIZED = {ALTER, "MATERIALIZED"};
+ static final String[] STMT_ALTER_OPERATOR = {ALTER, "OPERATOR"};
+ static final String[] STMT_ALTER_OUTLINE = {ALTER, "OUTLINE"};
+ static final String[] STMT_ALTER_PACKAGE = {ALTER, "PACKAGE"};
+ static final String[] STMT_ALTER_PROCEDURE = {ALTER, "PROCEDURE"};
+ static final String[] STMT_ALTER_PROFILE = {ALTER, "PROFILE"};
+ static final String[] STMT_ALTER_RESOURCE = {ALTER, "RESOURCE"};
+ static final String[] STMT_ALTER_ROLE = {ALTER, "ROLE"};
+ static final String[] STMT_ALTER_ROLLBACK = {ALTER, "ROLLBACK"};
+ static final String[] STMT_ALTER_SEQUENCE = {ALTER, "SEQUENCE"};
+ static final String[] STMT_ALTER_SESSION = {ALTER, "SESSION"};
+ static final String[] STMT_ALTER_SYSTEM = {ALTER, "SYSTEM"};
+ static final String[] STMT_ALTER_TABLESPACE = {ALTER, "TABLESPACE"};
+ static final String[] STMT_ALTER_TRIGGER = {ALTER, "TRIGGER"};
+ static final String[] STMT_ALTER_TYPE = {ALTER, "TYPE"};
+ static final String[] STMT_ALTER_USER = {ALTER, "USER"};
+ static final String[] STMT_ALTER_VIEW = {ALTER, "VIEW"};
+
+ static final String[][] ALTER_PHRASES = { STMT_ALTER_CLUSTER, STMT_ALTER_DATABASE,
+ STMT_ALTER_DIMENSION, STMT_ALTER_DISKGROUP, STMT_ALTER_FUNCTION, STMT_ALTER_INDEX, STMT_ALTER_INDEXTYPE, STMT_ALTER_JAVA,
+ STMT_ALTER_MATERIALIZED, STMT_ALTER_OPERATOR, STMT_ALTER_OUTLINE, STMT_ALTER_PACKAGE, STMT_ALTER_PROCEDURE,
+ STMT_ALTER_PROFILE, STMT_ALTER_RESOURCE, STMT_ALTER_ROLE, STMT_ALTER_ROLLBACK, STMT_ALTER_SEQUENCE,
+ STMT_ALTER_SESSION, STMT_ALTER_SYSTEM, STMT_ALTER_TABLESPACE, STMT_ALTER_TRIGGER, STMT_ALTER_TYPE,
+ STMT_ALTER_USER, STMT_ALTER_VIEW
+ };
+
+ static final String[] STMT_ANALYZE = {"ANALYZE"};
+ static final String[] STMT_ASSOCIATE_STATISTICS = {"ASSOCIATE", "STATISTICS"};
+ static final String[] STMT_AUDIT = {"AUDIT"};
+ static final String[] STMT_COMMIT = {"COMMIT"};
+ static final String[] STMT_COMMENT_ON = {"COMMENT", "ON"};
+
+ static final String[] STMT_CREATE_CLUSTER = {CREATE, "CLUSTER"};
+ static final String[] STMT_CREATE_CONTEXT = {CREATE, "CONTEXT"};
+ static final String[] STMT_CREATE_CONTROLFILE = {CREATE, "CONTROLFILE"};
+ static final String[] STMT_CREATE_DATABASE = {CREATE, "DATABASE"};
+ static final String[] STMT_CREATE_DIMENSION = {CREATE, "DIMENSION"};
+ static final String[] STMT_CREATE_DIRECTORY = {CREATE, "DIRECTORY"};
+ static final String[] STMT_CREATE_DISKGROUP = {CREATE, "DISKGROUP"};
+ static final String[] STMT_CREATE_FUNCTION = {CREATE, "FUNCTION"}; // PARSE UNTIL '/'
+ static final String[] STMT_CREATE_INDEX = {CREATE, "INDEX"};
+ static final String[] STMT_CREATE_INDEXTYPE = {CREATE, "INDEXTYPE"};
+ static final String[] STMT_CREATE_JAVA = {CREATE, "JAVA"};
+ static final String[] STMT_CREATE_LIBRARY = {CREATE, "LIBRARY"}; // PARSE UNTIL '/'
+ static final String[] STMT_CREATE_MATERIALIZED = {CREATE, "MATERIALIZED"};
+ static final String[] STMT_CREATE_OPERATOR = {CREATE, "OPERATOR"};
+ static final String[] STMT_CREATE_OR_REPLACE_DIRECTORY = {CREATE, "OR", "REPLACE", "DIRECTORY"}; // PARSE UNTIL '/'
+ static final String[] STMT_CREATE_OR_REPLACE_FUNCTION = {CREATE, "OR", "REPLACE", "FUNCTION"}; // PARSE UNTIL '/'
+ static final String[] STMT_CREATE_OR_REPLACE_LIBRARY = {CREATE, "OR", "REPLACE", "LIBRARY"}; // PARSE UNTIL '/'
+ static final String[] STMT_CREATE_OR_REPLACE_OUTLINE = {CREATE,"OR", "REPLACE", "OUTLINE"}; // PARSE UNTIL '/'
+ static final String[] STMT_CREATE_OR_REPLACE_PACKAGE = {CREATE,"OR", "REPLACE", "PACKAGE"};
+ static final String[] STMT_CREATE_OR_REPLACE_PUBLIC_SYNONYM = {CREATE, "OR", "REPLACE", "PUBLIC", "SYNONYM"};
+ static final String[] STMT_CREATE_OR_REPLACE_SYNONYM = {CREATE, "OR", "REPLACE", "SYNONYM"};
+ static final String[] STMT_CREATE_OR_REPLACE_TRIGGER = {CREATE, "OR", "REPLACE", "TRIGGER"}; // PARSE UNTIL '/
+ static final String[] STMT_CREATE_OR_REPLACE_TYPE = {CREATE, "OR", "REPLACE", "TYPE"};
+ static final String[] STMT_CREATE_OUTLINE = {CREATE, "OUTLINE"}; // PARSE UNTIL '/'
+ static final String[] STMT_CREATE_PACKAGE = {CREATE, "PACKAGE"}; // PARSE UNTIL '/'
+ static final String[] STMT_CREATE_PFILE = {CREATE, "PFILE"};
+ static final String[] STMT_CREATE_PROCEDURE = {CREATE, "PROCEDURE"}; // PARSE UNTIL '/'
+ static final String[] STMT_CREATE_PROFILE = {CREATE, "PROFILE"};
+ static final String[] STMT_CREATE_PUBLIC_DATABASE = {CREATE, "PUBLIC", "DATABASE"};
+ static final String[] STMT_CREATE_PUBLIC_ROLLBACK = {CREATE, "PUBLIC", "ROLLBACK"};
+ static final String[] STMT_CREATE_PUBLIC_SYNONYM = {CREATE, "PUBLIC", "SYNONYM"};
+ static final String[] STMT_CREATE_ROLE = {CREATE, "ROLE"};
+ static final String[] STMT_CREATE_ROLLBACK = {CREATE, "ROLLBACK"};
+ static final String[] STMT_CREATE_SEQUENCE = {CREATE, "SEQUENCE"};
+ static final String[] STMT_CREATE_SPFILE = {CREATE, "SPFILE"};
+ static final String[] STMT_CREATE_SYNONYM = {CREATE, "SYNONYM"};
+ static final String[] STMT_CREATE_TABLESPACE = {CREATE, "TABLESPACE"};
+ static final String[] STMT_CREATE_TRIGGER = {CREATE, "TRIGGER"};
+ static final String[] STMT_CREATE_TYPE = {CREATE, "TYPE"};
+ static final String[] STMT_CREATE_USER = {CREATE, "USER"};
+ static final String[] STMT_CREATE_UNIQUE_INDEX = {CREATE, "UNIQUE", "INDEX"};
+ static final String[] STMT_CREATE_BITMAP_INDEX = {CREATE, "BITMAP", "INDEX"};
+
+ public static final String[][] CREATE_PHRASES = {
+ STMT_CREATE_CLUSTER, STMT_CREATE_CONTEXT, STMT_CREATE_CONTROLFILE, STMT_CREATE_DATABASE, STMT_CREATE_DIMENSION,
+ STMT_CREATE_DIRECTORY, STMT_CREATE_DISKGROUP, STMT_CREATE_FUNCTION, STMT_CREATE_INDEX, STMT_CREATE_INDEXTYPE,
+ STMT_CREATE_JAVA, STMT_CREATE_MATERIALIZED, STMT_CREATE_OPERATOR, STMT_CREATE_OR_REPLACE_DIRECTORY,
+ STMT_CREATE_OR_REPLACE_OUTLINE,
+ STMT_CREATE_OR_REPLACE_PUBLIC_SYNONYM, STMT_CREATE_OR_REPLACE_SYNONYM,
+ STMT_CREATE_OR_REPLACE_TYPE, STMT_CREATE_OUTLINE, STMT_CREATE_PACKAGE, STMT_CREATE_PFILE, STMT_CREATE_PROCEDURE,
+ STMT_CREATE_PROFILE, STMT_CREATE_PUBLIC_DATABASE, STMT_CREATE_PUBLIC_ROLLBACK, STMT_CREATE_PUBLIC_SYNONYM, STMT_CREATE_ROLE,
+ STMT_CREATE_ROLLBACK, STMT_CREATE_SEQUENCE, STMT_CREATE_SPFILE, STMT_CREATE_SYNONYM, STMT_CREATE_TABLESPACE,
+ STMT_CREATE_TYPE, STMT_CREATE_USER, STMT_CREATE_UNIQUE_INDEX, STMT_CREATE_BITMAP_INDEX,
+ STMT_CREATE_TABLESPACE, STMT_CREATE_PROCEDURE
+ };
+
+ public static final String[][] IGNORABLE_CREATE_PHRASES_WITH_SLASHES = {
+ STMT_CREATE_LIBRARY, STMT_CREATE_OR_REPLACE_FUNCTION,
+ STMT_CREATE_OR_REPLACE_LIBRARY,
+ STMT_CREATE_OR_REPLACE_PACKAGE, STMT_CREATE_OR_REPLACE_TRIGGER,
+ STMT_CREATE_TRIGGER
+ };
+
+
+ static final String[] STMT_DISASSOCIATE_STATISTICS = {"DISASSOCIATE", "STATISTICS"};
+
+ static final String[] STMT_DROP_CLUSTER = {DROP, "CLUSTER"};
+ static final String[] STMT_DROP_CONTEXT = {DROP, "CONTEXT"};
+ static final String[] STMT_DROP_DATABASE = {DROP, "DATABASE"};
+ static final String[] STMT_DROP_DIMENSION = {DROP, "DIMENSION"};
+ static final String[] STMT_DROP_DIRECTORY = {DROP, "DIRECTORY"};
+ static final String[] STMT_DROP_DISKGROUP = {DROP, "DISKGROUP"};
+ static final String[] STMT_DROP_FUNCTION = {DROP, "FUNCTION"};
+ static final String[] STMT_DROP_INDEX = {DROP, "INDEX"};
+ static final String[] STMT_DROP_INDEXTYPE = {DROP, "INDEXTYPE"};
+ static final String[] STMT_DROP_JAVA = {DROP, "JAVA"};
+ static final String[] STMT_DROP_LIBRARY = {DROP, "LIBRARY"};
+ static final String[] STMT_DROP_MATERIALIZED = {DROP, "MATERIALIZED"};
+ static final String[] STMT_DROP_OPERATOR = {DROP, "OPERATOR"};
+ static final String[] STMT_DROP_OUTLINE = {DROP, "OUTLINE"};
+ static final String[] STMT_DROP_PACKAGE = {DROP, "PACKAGE"};
+ static final String[] STMT_DROP_PROCEDURE = {DROP, "PROCEDURE"};
+ static final String[] STMT_DROP_PROFILE = {DROP, "PROFILE"};
+ static final String[] STMT_DROP_ROLE = {DROP, "ROLE"};
+ static final String[] STMT_DROP_ROLLBACK = {DROP, "ROLLBACK"};
+ static final String[] STMT_DROP_SEQUENCE = {DROP, "SEQUENCE"};
+ static final String[] STMT_DROP_SYNONYM = {DROP, "SYNONYM"};
+ static final String[] STMT_DROP_TABLESPACE = {DROP, "TABLESPACE"};
+ static final String[] STMT_DROP_TRIGGER = {DROP, "TRIGGER"};
+ static final String[] STMT_DROP_TYPE = {DROP, "TYPE"};
+ static final String[] STMT_DROP_USER = {DROP, "USER"};
+
+ static final String[] STMT_DROP_PUBLIC_DATABASE = {DROP, "PUBLIC", "DATABASE"};
+ static final String[] STMT_DROP_PUBLIC_SYNONYM = {DROP, "PUBLIC", "SYNONYM"};
+
+ static final String[][] DROP_PHRASES = {
+ STMT_DROP_CLUSTER, STMT_DROP_CONTEXT, STMT_DROP_DATABASE, STMT_DROP_DIMENSION, STMT_DROP_DIRECTORY, STMT_DROP_DISKGROUP,
+ STMT_DROP_FUNCTION, STMT_DROP_INDEX, STMT_DROP_INDEXTYPE, STMT_DROP_JAVA, STMT_DROP_LIBRARY, STMT_DROP_MATERIALIZED,
+ STMT_DROP_OPERATOR, STMT_DROP_OUTLINE, STMT_DROP_PACKAGE, STMT_DROP_PROCEDURE, STMT_DROP_PROFILE, STMT_DROP_ROLE,
+ STMT_DROP_ROLLBACK, STMT_DROP_SEQUENCE, STMT_DROP_SYNONYM, STMT_DROP_TABLESPACE, STMT_DROP_TRIGGER, STMT_DROP_TYPE,
+ STMT_DROP_USER, STMT_DROP_PUBLIC_DATABASE, STMT_DROP_PUBLIC_SYNONYM
+ };
+
+ static final String[] STMT_EXPLAIN_PLAN = {"EXPLAIN", "PLAN"};
+ static final String[] STMT_FLASHBACK = {"FLASHBACK"};
+ static final String[] STMT_GRANT = {GRANT};
+ static final String[] STMT_LOCK_TABLE = {"LOCK", "TABLE"};
+ static final String[] STMT_MERGE = {"MERGE"};
+ static final String[] STMT_NESTED_TABLE = {"NESTED", "TABLE"};
+ static final String[] STMT_NOAUDIT = {"NOAUDIT"};
+ static final String[] STMT_PURGE = {"PURGE"};
+ static final String[] STMT_RENAME = {"RENAME"};
+ static final String[] STMT_REVOKE = {"REVOKE"};
+ static final String[] STMT_ROLLBACK_TO_SAVEPOINT = {"ROLLBACK", "TO", "SAVEPOINT"};
+ static final String[] STMT_ROLLBACK_WORK = {"ROLLBACK", "WORK"};
+ static final String[] STMT_ROLLBACK = {"ROLLBACK"};
+ static final String[] STMT_SAVEPOINT = {"SAVEPOINT"};
+ static final String[] STMT_SET_CONSTRAINT = {SET, "CONSTRAINT"};
+ static final String[] STMT_SET_CONSTRAINTS = {SET, "CONSTRAINTS"};
+ static final String[] STMT_SET_ROLE = {SET, "ROLE"};
+ static final String[] STMT_SET_TRANSACTION = {SET, "TRANSACTION"};
+ static final String[] STMT_TRUNCATE = {"TRUNCATE"};
+
+ static final String[][] SET_PHRASES = {
+ STMT_SET_CONSTRAINT, STMT_SET_CONSTRAINTS, STMT_SET_ROLE, STMT_SET_TRANSACTION
+ };
+
+ static final String[][] MISC_PHRASES = {
+ STMT_ANALYZE, STMT_ASSOCIATE_STATISTICS, STMT_AUDIT, STMT_COMMIT, STMT_COMMENT_ON, STMT_DISASSOCIATE_STATISTICS,
+ STMT_EXPLAIN_PLAN, STMT_FLASHBACK, STMT_GRANT, STMT_LOCK_TABLE, STMT_MERGE, STMT_NESTED_TABLE, STMT_NOAUDIT, STMT_PURGE,
+ STMT_RENAME, STMT_REVOKE, STMT_ROLLBACK_TO_SAVEPOINT, STMT_ROLLBACK_WORK, STMT_ROLLBACK, STMT_SAVEPOINT, STMT_TRUNCATE
+ };
+ }
+
+ interface OracleDataTypes {
+ static final String[] DTYPE_CHAR_ORACLE = {"CHAR"}; //CHAR(size [BYTE | CHAR])
+ static final String[] DTYPE_VARCHAR2 = {"VARCHAR2"}; // VARCHAR2(size [BYTE | CHAR])
+ static final String[] DTYPE_NVARCHAR2 = {"NVARCHAR2"}; // NVARCHAR2(size)
+ static final String[] DTYPE_NUMBER = {"NUMBER"}; // NUMBER(p,s)
+ static final String[] DTYPE_BINARY_FLOAT = {"BINARY_FLOAT "};
+ static final String[] DTYPE_BINARY_DOUBLE = {"BINARY_DOUBLE"};
+ static final String[] DTYPE_LONG = {"LONG"};
+ static final String[] DTYPE_LONG_RAW = {"LONG", "RAW"};
+ static final String[] DTYPE_RAW = {"RAW"}; // RAW(size)
+ static final String[] DTYPE_BLOB = {"BLOB"};
+ static final String[] DTYPE_CLOB = {"CLOB"};
+ static final String[] DTYPE_NCLOB = {"NCLOB"};
+ static final String[] DTYPE_BFILE = {"BFILE"};
+ static final String[] DTYPE_INTERVAL_YEAR = {"INTERVAL", "YEAR"}; //INTERVAL YEAR (year_precision) TO MONTH
+ static final String[] DTYPE_INTERVAL_DAY = {"INTERVAL", "DAY"}; // INTERVAL DAY (day_precision) TO SECOND (fractional_seconds_precision)
+
+ static final List<String[]> CUSTOM_DATATYPE_START_PHRASES =
+ Arrays.asList(new String[][] {
+ DTYPE_CHAR_ORACLE, DTYPE_VARCHAR2, DTYPE_NVARCHAR2, DTYPE_NUMBER, DTYPE_BINARY_FLOAT, DTYPE_BINARY_DOUBLE,
+ DTYPE_LONG, DTYPE_LONG_RAW, DTYPE_RAW, DTYPE_BLOB, DTYPE_CLOB, DTYPE_NCLOB, DTYPE_BFILE, DTYPE_INTERVAL_YEAR,
+ DTYPE_INTERVAL_DAY
+ });
+
+ static final List<String> CUSTOM_DATATYPE_START_WORDS =
+ Arrays.asList(new String[] {"VARCHAR2", "NVARCHAR2", "NUMBER",
+ "BINARY_FLOAT", "BINARY_DOUBLE", "LONG", "RAW", "BLOB", "CLOB", "NCLOB", "BFILE", "INTERVAL"
+ });
+ }
+}
Property changes on: branches/ddl_sequencer/extensions/dna-sequencer-ddl/src/main/java/org/jboss/dna/sequencer/ddl/dialect/oracle/OracleDdlConstants.java
___________________________________________________________________
Name: svn:mime-type
+ text/plain
Added: branches/ddl_sequencer/extensions/dna-sequencer-ddl/src/main/java/org/jboss/dna/sequencer/ddl/dialect/oracle/OracleDdlParser.java
===================================================================
--- branches/ddl_sequencer/extensions/dna-sequencer-ddl/src/main/java/org/jboss/dna/sequencer/ddl/dialect/oracle/OracleDdlParser.java (rev 0)
+++ branches/ddl_sequencer/extensions/dna-sequencer-ddl/src/main/java/org/jboss/dna/sequencer/ddl/dialect/oracle/OracleDdlParser.java 2009-10-02 16:13:40 UTC (rev 1280)
@@ -0,0 +1,786 @@
+/*
+ * JBoss DNA (http://www.jboss.org/dna)
+ * 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.
+ * See the AUTHORS.txt file in the distribution for a full listing of
+ * individual contributors.
+ *
+ * JBoss DNA is free software. Unless otherwise indicated, all code in JBoss DNA
+ * is licensed to you 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.
+ *
+ * JBoss DNA 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 software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.dna.sequencer.ddl.dialect.oracle;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.jboss.dna.common.text.ParsingException;
+import org.jboss.dna.sequencer.ddl.DdlTokenStream;
+import org.jboss.dna.sequencer.ddl.StandardDdlParser;
+import org.jboss.dna.sequencer.ddl.datatype.DataType;
+import org.jboss.dna.sequencer.ddl.datatype.DataTypeParser;
+import org.jboss.dna.sequencer.ddl.statement.AlterTable;
+import org.jboss.dna.sequencer.ddl.statement.Column;
+import org.jboss.dna.sequencer.ddl.statement.Index;
+import org.jboss.dna.sequencer.ddl.statement.Statement;
+import org.jboss.dna.sequencer.ddl.statement.TableConstraint;
+import org.jboss.dna.sequencer.ddl.statement.TypedStatement;
+
+
+/**
+ * Oracle-specific DDL Parser. Includes custom data types as well as custom DDL statements.
+ *
+ */
+public class OracleDdlParser extends StandardDdlParser implements OracleDdlConstants {
+
+ static List<String[]> oracleDataTypeStrings = new ArrayList<String[]>();
+
+ public OracleDdlParser() {
+ super();
+
+ setDatatypeParser(new OracleDataTypeParser());
+ initialize();
+ }
+
+ private void initialize() {
+ setTerminator(DEFAULT_TERMINATOR);
+
+ setDoUseTerminator(true);
+
+ oracleDataTypeStrings.addAll(OracleDataTypes.CUSTOM_DATATYPE_START_PHRASES); //
+ }
+
+ /**
+ * Method allows registering Oracle-specific Statement Start Keyword Phrases and Keywords
+ *
+ *
+ * {@inheritDoc}
+ *
+ * @see org.jboss.dna.sequencer.ddl.StandardDdlParser#registerWords(org.jboss.dna.sequencer.ddl.DdlTokenStream)
+ */
+ @Override
+ protected void registerWords( DdlTokenStream tokens ) {
+ super.registerWords(tokens);
+
+ registerKeyWords(CUSTOM_KEYWORDS);
+ registerKeyWords(OracleDataTypes.CUSTOM_DATATYPE_START_WORDS);
+
+ registerStatementStartPhrase(OracleStatementStartPhrases.ALTER_PHRASES);
+ registerStatementStartPhrase(OracleStatementStartPhrases.CREATE_PHRASES);
+ registerStatementStartPhrase(OracleStatementStartPhrases.IGNORABLE_CREATE_PHRASES_WITH_SLASHES);
+ registerStatementStartPhrase(OracleStatementStartPhrases.DROP_PHRASES);
+ registerStatementStartPhrase(OracleStatementStartPhrases.SET_PHRASES);
+ registerStatementStartPhrase(OracleStatementStartPhrases.MISC_PHRASES);
+
+ }
+
+ /**
+ *
+ * {@inheritDoc}
+ *
+ * @see org.jboss.dna.sequencer.ddl.StandardDdlParser#parseCustomStatement(org.jboss.dna.sequencer.ddl.DdlTokenStream)
+ */
+ @Override
+ protected Statement parseCustomStatement(DdlTokenStream tokens)
+ throws ParsingException {
+ Statement stmt = null;
+
+ if( tokens.matches(OracleStatementStartPhrases.STMT_COMMENT_ON) ) {
+ stmt = parseCommentStatement(tokens);
+ } else if( tokens.matches(OracleStatementStartPhrases.STMT_NESTED_TABLE) ) {
+ // EXAMPLES:
+ // NESTED TABLE employees STORE AS deptemps;
+ // or MODIFY NESTED TABLE employees RETURN AS deptemps;
+ tokens.consume("NESTED", TABLE, DdlTokenStream.ANY_VALUE, DdlTokenStream.ANY_VALUE, "AS", DdlTokenStream.ANY_VALUE);
+ } else if( tokens.matches(SET) ) {
+ stmt = parseSetStatement(tokens);
+ } else if( tokens.matches(GRANT)) {
+ stmt = parseGrantStatement(tokens);
+ } else {
+ stmt = parseIgnorableStatement(tokens);
+ }
+
+ if( stmt == null ) {
+ stmt = super.parseCustomStatement(tokens);
+ }
+ return stmt;
+ }
+
+ private Statement parseIgnorableStatement(DdlTokenStream tokens ) throws ParsingException {
+ Statement result = null;
+ for( String[] phrase : OracleStatementStartPhrases.IGNORABLE_CREATE_PHRASES_WITH_SLASHES ) {
+ if( tokens.matches(phrase) ) {
+ tokens.consume(CREATE);
+ result = parseIgnorableSlashedStatement(tokens, getStatementTypeName(phrase));
+ break;
+ }
+ }
+ if( result == null ) {
+ for( String[] phrase : OracleStatementStartPhrases.ALTER_PHRASES ) {
+ // NOTE: Shouldn't get here. Alter statements are handled at a higher level
+ if( tokens.matches(phrase) ) {
+ tokens.consume(ALTER);
+ result = parseIgnorableStatement(tokens, getStatementTypeName(phrase));
+ consumeSlash(tokens);
+ break;
+ }
+ }
+ }
+ if( result == null ) {
+ for( String[] phrase : OracleStatementStartPhrases.CREATE_PHRASES ) {
+ // NOTE: Shouldn't get here. Alter statements are handled at a higher level
+ if( tokens.matches(phrase) ) {
+ tokens.consume(CREATE);
+ result = parseIgnorableStatement(tokens, getStatementTypeName(phrase));
+ consumeSlash(tokens);
+ }
+ }
+ }
+ if( result == null ) {
+ for( String[] phrase : OracleStatementStartPhrases.DROP_PHRASES ) {
+ // NOTE: Shouldn't get here. Alter statements are handled at a higher level
+ if( tokens.matches(phrase) ) {
+ tokens.consume(DROP);
+ result = parseIgnorableStatement(tokens, getStatementTypeName(phrase));
+ consumeSlash(tokens);
+ break;
+ }
+ }
+ }
+ if( result == null ) {
+ for( String[] phrase : OracleStatementStartPhrases.SET_PHRASES ) {
+ // NOTE: Shouldn't get here. Alter statements are handled at a higher level
+ if( tokens.matches(phrase) ) {
+ tokens.consume(SET);
+ result = parseIgnorableStatement(tokens, getStatementTypeName(phrase));
+ consumeSlash(tokens);
+ break;
+ }
+ }
+ }
+ if( result == null ) {
+ for( String[] phrase : OracleStatementStartPhrases.MISC_PHRASES ) {
+ // NOTE: Shouldn't get here. Alter statements are handled at a higher level
+ if( tokens.matches(phrase) ) {
+ tokens.consume();
+ result = parseIgnorableStatement(tokens, getStatementTypeName(phrase));
+ consumeSlash(tokens);
+ break;
+ }
+ }
+ }
+
+ return result;
+
+ }
+
+ /**
+ *
+ * {@inheritDoc}
+ *
+ * @see org.jboss.dna.sequencer.ddl.StandardDdlParser#parseCreateStatement(org.jboss.dna.sequencer.ddl.DdlTokenStream, boolean)
+ */
+ @Override
+ protected Statement parseCreateStatement(DdlTokenStream tokens, boolean inSchema) throws ParsingException {
+ Statement result = null;
+
+ if( tokens.matches(OracleStatementStartPhrases.STMT_CREATE_INDEX)
+ || tokens.matches(OracleStatementStartPhrases.STMT_CREATE_UNIQUE_INDEX)
+ || tokens.matches(OracleStatementStartPhrases.STMT_CREATE_BITMAP_INDEX)) {
+ result = parseCreateIndex(tokens);
+ } else {
+ for( String[] phrase : OracleStatementStartPhrases.IGNORABLE_CREATE_PHRASES_WITH_SLASHES ) {
+ if( tokens.matches(phrase) ) {
+ tokens.consume(CREATE);
+ result = parseIgnorableSlashedStatement(tokens, getStatementTypeName(phrase));
+ break;
+ }
+ }
+ if( result == null ) {
+ for( String[] phrase : OracleStatementStartPhrases.CREATE_PHRASES ) {
+ if( tokens.matches(phrase) ) {
+ tokens.consume(CREATE);
+ result = parseIgnorableStatement(tokens, getStatementTypeName(phrase));
+ consumeSlash(tokens);
+ break;
+ }
+ }
+ }
+ }
+
+ if( result == null ) {
+ result = super.parseCreateStatement(tokens, inSchema);
+ }
+
+ return result;
+ }
+
+ /**
+ *
+ * {@inheritDoc}
+ *
+ * @see org.jboss.dna.sequencer.ddl.StandardDdlParser#parseGrantStatement(org.jboss.dna.sequencer.ddl.DdlTokenStream)
+ */
+ @Override
+ protected Statement parseGrantStatement( DdlTokenStream tokens ) throws ParsingException {
+ if( tokens.matches(GRANT, DdlTokenStream.ANY_VALUE, "TO")) {
+ tokens.consume(GRANT);
+ String privilege = tokens.consume();
+ tokens.consume("TO");
+ String toValue = tokens.consume();
+ Statement stmt = new TypedStatement();
+ String value = parseUntilTerminator(tokens);
+ stmt.setValue(value);
+ stmt.setType("GRANT" + SPACE + privilege + SPACE + "TO" + SPACE + toValue);
+ return stmt;
+ }
+ if( tokens.matches(GRANT, DdlTokenStream.ANY_VALUE, "ON")) {
+ tokens.consume(GRANT);
+ String privilege = tokens.consume();
+ tokens.consume("ON");
+ String toValue = tokens.consume();
+ Statement stmt = new TypedStatement();
+ String value = parseUntilTerminator(tokens);
+ stmt.setValue(value);
+ stmt.setType("GRANT" + SPACE + privilege + SPACE + "ON" + SPACE + toValue);
+ return stmt;
+ }
+ if( tokens.matches(GRANT, CREATE) ||
+ tokens.matches(GRANT, ALTER) ||
+ tokens.matches(GRANT, DROP) ||
+ tokens.matches(GRANT, "EXECUTE") ||
+ tokens.matches(GRANT, "MANAGE") ||
+ tokens.matches(GRANT, "QUERY") ||
+ tokens.matches(GRANT, "ON", "COMMIT") ||
+ tokens.matches(GRANT, "ANY") ||
+ tokens.matches(GRANT, "SELECT") ||
+ tokens.matches(GRANT, "RESTRICTED") ||
+ tokens.matches(GRANT, "FLASHBACK") ||
+ tokens.matches(GRANT, "GLOBAL") ||
+ tokens.matches(GRANT, "DEBUG") ||
+ tokens.matches(GRANT, "GLOBAL") ||
+ tokens.matches(GRANT, "ADVISOR") ||
+ tokens.matches(GRANT, "ADMINISTER") ||
+ tokens.matches(GRANT, "BACKUP") ||
+ tokens.matches(GRANT, "LOCK") ||
+ tokens.matches(GRANT, "UPDATE") ||
+ tokens.matches(GRANT, "DELETE") ||
+ tokens.matches(GRANT, "INSERT") ||
+ tokens.matches(GRANT, "UNLIMITED") ||
+ tokens.matches(GRANT, "UNDER") ||
+ tokens.matches(GRANT, "ANALYZE") ||
+ tokens.matches(GRANT, "AUDIT") ||
+ tokens.matches(GRANT, "COMMENT") ||
+ tokens.matches(GRANT, "EXEMPT") ||
+ tokens.matches(GRANT, "FORCE") ||
+ tokens.matches(GRANT, "RESUMABLE") ||
+ tokens.matches(GRANT, "SYSDBA") ||
+ tokens.matches(GRANT, "REFERENCES") ||
+ tokens.matches(GRANT, "SYSOPER") ||
+ tokens.matches(GRANT, "WRITE") ) {
+ tokens.consume(GRANT);
+ String nextTok = tokens.consume() + SPACE + tokens.consume() + SPACE + tokens.consume();
+ Statement stmt = new TypedStatement();
+ String value = parseUntilTerminator(tokens);
+ stmt.setValue(value);
+ stmt.setType("GRANT" + " " + nextTok);
+ return stmt;
+ }
+
+
+ return null;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.jboss.dna.sequencer.ddl.StandardDdlParser#parseAlterTableStatement(org.jboss.dna.sequencer.ddl.DdlTokenStream)
+ */
+ @Override
+ protected Statement parseAlterTableStatement(DdlTokenStream tokens)
+ throws ParsingException {
+ if( tokens.matches("ALTER", "TABLE", DdlTokenStream.ANY_VALUE, "ADD")) {
+ tokens.consume(); // consumes 'ALTER'
+ tokens.consume("TABLE");
+ String tableName = parseName(tokens);
+ tokens.consume("ADD");
+
+ //System.out.println(" >> PARSING ALTER STATEMENT >> TABLE Name = " + tableName);
+
+ AlterTable alterTableStatement = new AlterTable(tableName);
+ TableConstraint constraint = parseTableConstraint(tokens);
+ if( constraint != null ) {
+ alterTableStatement.addConstraint(constraint);
+ } else {
+ // This segment can also be enclosed in "()" brackets to handle multiple Column ADDs
+ if( tokens.matches("(", "REF")) {
+ //ALTER TABLE staff ADD (REF(dept) WITH ROWID);
+ tokens.consume("(", "REF", "(");
+ parseName(tokens);
+ tokens.consume(")", "WITH", "ROWID");
+
+ } else if( tokens.matches("(", "SCOPE") ) {
+ // ALTER TABLE staff ADD (SCOPE FOR (dept) IS offices);
+ tokens.consume("(", "SCOPE", "FOR", "(");
+ parseName(tokens);
+ tokens.consume(")", "IS");
+ parseName(tokens);
+ tokens.consume(")");
+ } else if( tokens.matches('(')) {
+ List<Column> columns = parseColumns(tokens);
+ for( Column newColumn : columns ) {
+ alterTableStatement.addColumn(newColumn);
+ }
+ } else {
+ // Assume single ADD COLUMN
+ Column newColumn = parseSingleTerminatedColumnDefinition(tokens);
+
+ alterTableStatement.addColumn(newColumn);
+ }
+ }
+ consumeTerminator(tokens);
+ return alterTableStatement;
+ } else if( tokens.matches(OracleStatementStartPhrases.STMT_ALTER_INDEX) ){
+ tokens.consume(OracleStatementStartPhrases.STMT_ALTER_INDEX); // consumes 'ALTER'
+ String indexName = parseName(tokens);
+ Statement stmt = new TypedStatement();
+ stmt.setName(getStatementTypeName(OracleStatementStartPhrases.STMT_ALTER_INDEX));
+ StringBuffer sb = new StringBuffer();
+ sb.append("ALTER INDEX").append(SPACE).append(indexName).append(parseUntilTerminator(tokens));
+ consumeTerminator(tokens);
+ return stmt;
+
+ } else if(tokens.matches("ALTER", "TABLE", DdlTokenStream.ANY_VALUE, "RENAME")) {
+ // ALTER TABLE customers RENAME TO my_customers;
+ // ALTER TABLE customers RENAME CONSTRAINT cust_fname_nn TO cust_firstname_nn;
+ tokens.consume(); // consumes 'ALTER'
+ tokens.consume("TABLE");
+ String oldName = parseName(tokens);
+
+ AlterTable alterTableStatement = new AlterTable(oldName);
+
+ if( tokens.canConsume("RENAME", "TO") ) {
+ alterTableStatement.setActionValue("RENAME TO" + parseUntilTerminator(tokens));
+ } else if( tokens.canConsume("RENAME", "COLUMN") ) {
+ alterTableStatement.setActionValue("RENAME COLUMN" + parseUntilTerminator(tokens));
+ } else if( tokens.canConsume("RENAME", "CONSTRAINT") ) {
+ alterTableStatement.setActionValue("RENAME CONSTRAINT" + parseUntilTerminator(tokens));
+ }
+ consumeTerminator(tokens);
+ return alterTableStatement;
+ }
+
+ return super.parseAlterTableStatement(tokens);
+ }
+
+ /**
+ *
+ * {@inheritDoc}
+ *
+ * @see org.jboss.dna.sequencer.ddl.StandardDdlParser#parseAlterStatement(org.jboss.dna.sequencer.ddl.DdlTokenStream)
+ */
+ @Override
+ protected Statement parseAlterStatement(DdlTokenStream tokens) throws ParsingException {
+ Statement result = null;
+
+ for( String[] phrase : OracleStatementStartPhrases.ALTER_PHRASES ) {
+ if( tokens.matches(phrase) ) {
+ tokens.consume("ALTER");
+ result = parseIgnorableStatement(tokens, getStatementTypeName(phrase));
+ break;
+ }
+ }
+
+ if( result == null ) {
+ result = super.parseAlterStatement(tokens);
+ }
+
+ return result;
+ }
+
+ /**
+ * Parses DDL CREATE INDEX {@link Statement}
+ *
+ * @param tokens
+ * @return the parsed CREATE INDEX {@link Statement}
+ * @throws ParsingException
+ */
+ private Statement parseCreateIndex( DdlTokenStream tokens ) throws ParsingException {
+ // CREATE INDEX STR_MODEL_NDX ON MMR_STRING_ATTRS (MODEL_ID);
+ tokens.consume(); // CREATE
+ boolean isUnique = tokens.canConsume("UNIQUE");
+ tokens.canConsume("BITMAP");
+ tokens.consume("INDEX");
+ String indexName = consumeIdentifier(tokens);
+ tokens.consume("ON");
+ tokens.canConsume("CLUSTER");
+ String tableName = consumeIdentifier(tokens);
+
+ //System.out.println(" >> PARSING Create INDEX >> Name = " + indexName + " For TABLE = " + tableName);
+
+ List<String> columnNameList = new ArrayList<String>();
+ try {
+ if( tokens.matches('(')) {
+ tokens.consume();
+ columnNameList = parseColumnNameList(tokens);
+ tokens.consume(')');
+ }
+ } catch (ParsingException e) {
+ // Give up on parsing, probably a nested function (i.e. banned (lower(banned_name));
+ parseUntilTerminator(tokens);
+ }
+ Index newIndex = new Index(indexName, tableName, columnNameList);
+ newIndex.setUnique(isUnique);
+
+ consumeTerminator(tokens);
+
+ return newIndex;
+ }
+
+
+ private Statement parseCommentStatement( DdlTokenStream tokens ) throws ParsingException {
+ // COMMENT ON COLUMN CS_EXT_FILES.FILE_UID IS
+ // 'UNIQUE INTERNAL IDENTIFIER, NOT EXPOSED'
+ // %
+
+ /*
+ commentCommand
+ : 'COMMENT' 'ON'
+ ( 'TABLE' tableName
+ | 'VIEW' tableName
+ | 'INDEX' indexName
+ | 'COLUMN' columnName
+ | 'PROCEDURE' procedureId
+ | 'MATERIALIZED'? 'VIEW' tableName
+ ) 'IS' ('NULL' | (CharLiteral)+) commandEnd? //CharLiteral (',' unicodeCharLiteral)*) commandEnd?
+ ;
+ */
+ tokens.consume("COMMENT", "ON"); // consumes 'COMMENT' 'ON'
+ String obj = tokens.consume();
+ String objName = parseName(tokens);
+
+ //System.out.println(" >> FOUND [COMMENT ON] STATEMENT >> TABLE Name = " + objName);
+ String commentString = null;
+
+ tokens.consume("IS");
+ if( tokens.matches("NULL") ) {
+ tokens.consume("NULL");
+ } else {
+ commentString = parseUntilTerminator(tokens);
+ }
+
+ consumeTerminator(tokens);
+
+ return new CommentStatement(obj, objName, commentString);
+ }
+
+ /**
+ *
+ * {@inheritDoc}
+ *
+ * @see org.jboss.dna.sequencer.ddl.StandardDdlParser#parseSetStatement(org.jboss.dna.sequencer.ddl.DdlTokenStream)
+ */
+ @Override
+ protected Statement parseSetStatement(DdlTokenStream tokens)
+ throws ParsingException {
+ Statement result = null;
+
+ for( String[] phrase : OracleStatementStartPhrases.SET_PHRASES ) {
+ // NOTE: Shouldn't get here. Alter statements are handled at a higher level
+ if( tokens.matches(phrase) ) {
+ tokens.consume("SET");
+ result = parseIgnorableStatement(tokens, getStatementTypeName(phrase));
+ break;
+ }
+ }
+
+ return result;
+ }
+
+ /**
+ *
+ * {@inheritDoc}
+ *
+ * @see org.jboss.dna.sequencer.ddl.StandardDdlParser#parseDropStatement(org.jboss.dna.sequencer.ddl.DdlTokenStream)
+ */
+ @Override
+ protected Statement parseDropStatement( DdlTokenStream tokens ) throws ParsingException {
+ Statement result = null;
+
+ if( tokens.matches(StatementStartPhrases.STMT_DROP_TABLE )) {
+ // <drop table statement> ::=
+ // DROP TABLE <table name> [{CASCADE | RESTRICT} CONSTAINTS] [PURGE]
+ //
+ // <drop behavior> ::= CASCADE | RESTRICT
+ tokens.consume(StatementStartPhrases.STMT_DROP_TABLE);
+ String name = parseName(tokens);
+ result = new TypedStatement();
+ result.setName(name);
+ result.setType("DROP TABLE");
+
+ tokens.canConsume("CASCADE");
+ tokens.canConsume("CASCADE");
+ tokens.canConsume("RESTRICT");
+ tokens.canConsume("PURGE");
+ }
+ if( result == null ) {
+ for( String[] phrase : OracleStatementStartPhrases.DROP_PHRASES ) {
+ if( tokens.matches(phrase) ) {
+ tokens.consume("DROP");
+ String name = null;
+ if( !tokens.matches(getTerminator())) {
+ name = tokens.consume();
+ }
+ result = parseIgnorableStatement(tokens, getStatementTypeName(phrase));
+ result.setName(name);
+ break;
+ }
+ }
+ }
+ if( result == null ) {
+ result = super.parseDropStatement(tokens);
+ }
+ return result;
+ }
+
+ private Statement parseIgnorableSlashedStatement(DdlTokenStream tokens, String name) throws ParsingException {
+ TypedStatement stmt = null;
+
+ String value = parseUntilFwdSlash(tokens);
+ if( value != null ) {
+ stmt = new TypedStatement();
+ stmt.setType(name);
+ stmt.setValue(value);
+ }
+ tokens.consume("/");
+
+ //System.out.println(" >>> FOUND [" + stmt.getType() +"] STATEMENT TOKEN. IGNORING");
+ return stmt;
+ }
+
+ /**
+ * Various Oracle statements (i.e. "CREATE OR REPLACE PACKAGE", etc...) may contain multiple SQL statements that will be
+ * terminated by the semicolon, ';'. In these cases, the terminator is now the '/' character.
+ *
+ * @param tokens
+ * @return the parsed string.
+ * @throws ParsingException
+ */
+ private String parseUntilFwdSlash( DdlTokenStream tokens ) throws ParsingException {
+ StringBuffer sb = new StringBuffer();
+ while( tokens.hasNext() && !tokens.matches('/')) { // !tokens.matches(DdlTokenizer.STATEMENT_KEY) &&
+ sb.append(SPACE).append(tokens.consume());
+ }
+
+ return sb.toString();
+ }
+
+ private void consumeSlash( DdlTokenStream tokens ) throws ParsingException {
+ tokens.canConsume("/");
+ }
+
+ // ===========================================================================================================================
+ // PARSE OBJECTS
+ // ===========================================================================================================================
+
+ /**
+ * Oracle-specific COMMENT ON statement
+ */
+ public class CommentStatement extends TypedStatement {
+ private String comment = null;
+ private String targetType = null;
+ private String targetName = null;
+
+ public CommentStatement(String targetType, String targetName, String comment) {
+ super();
+ setType("COMMENT ON");
+ this.targetType = targetType;
+ this.targetName = targetName;
+ this.comment = comment;
+ }
+
+ public String getTargetType() {
+ return targetType;
+ }
+
+ public void setTargetType(String targetType) {
+ this.targetType = targetType;
+ }
+
+ public String getTargetName() {
+ return targetName;
+ }
+
+ public void setTargetName(String targetName) {
+ this.targetName = targetName;
+ }
+
+ public String getComment() {
+ return comment;
+ }
+
+ public void setComment(String comment) {
+ this.comment = comment;
+ }
+
+
+ // ===========================================================================================================================
+ // ===========================================================================================================================
+ }
+
+ /**
+ * This class provides custom data type parsing for Oracle-specific data types.
+ *
+ */
+ class OracleDataTypeParser extends DataTypeParser {
+
+ /*
+ * (non-Javadoc)
+ * @see org.jboss.dna.sequencer.ddl.datatype.DataTypeParser#parseCustomType(org.jboss.dna.common.text.DdlTokenStream)
+ */
+ @Override
+ protected DataType parseCustomType(DdlTokenStream tokens) throws ParsingException {
+ DataType result = null;
+ String typeName = null;
+
+ if( tokens.matches(OracleDataTypes.DTYPE_BINARY_FLOAT)) {
+ typeName = tokens.consume();
+ } else if( tokens.matches(OracleDataTypes.DTYPE_BINARY_DOUBLE) ) {
+ typeName = tokens.consume();
+ } else if( tokens.matches(OracleDataTypes.DTYPE_LONG) ){
+ typeName = tokens.consume();
+ } else if( tokens.matches(OracleDataTypes.DTYPE_LONG_RAW) ){
+ typeName = tokens.consume() + SPACE + tokens.consume();
+ } else if( tokens.matches(OracleDataTypes.DTYPE_BLOB) ){
+ typeName = tokens.consume();
+ } else if( tokens.matches(OracleDataTypes.DTYPE_CLOB) ){
+ typeName = tokens.consume();
+ } else if( tokens.matches(OracleDataTypes.DTYPE_NCLOB) ){
+ typeName = tokens.consume();
+ } else if( tokens.matches(OracleDataTypes.DTYPE_BFILE) ){
+ typeName = tokens.consume();
+ } else if(tokens.matches(OracleDataTypes.DTYPE_VARCHAR2)) {
+ // VARCHAR2(size [BYTE | CHAR])
+ typeName = tokens.consume(); // NAME
+ tokens.consume('(');
+ int length = parseInteger(tokens);
+ if( tokens.matchesAnyOf("BYTE", "CHAR") ) {
+ tokens.consume();
+ }
+ tokens.consume(')');
+ result = new DataType(typeName, length);
+ } else if(tokens.matches(OracleDataTypes.DTYPE_RAW)) {
+ typeName = tokens.consume();
+ int length = parseBracketedInteger(tokens);
+
+ result = new DataType(typeName, length);
+ } else if(tokens.matches(OracleDataTypes.DTYPE_NVARCHAR2)) {
+ typeName = tokens.consume();
+ int length = parseBracketedInteger(tokens);
+
+ result = new DataType(typeName, length);
+ } else if(tokens.matches(OracleDataTypes.DTYPE_NUMBER)) {
+ typeName = tokens.consume();
+ int precision = 0;
+ int scale = 0;
+ if( tokens.matches('(')) {
+ tokens.consume('(');
+ precision = parseInteger(tokens);
+ if( tokens.canConsume(',') ) {
+ scale = parseInteger(tokens);
+ } else {
+ scale = getDefaultScale();
+ }
+ tokens.consume(')');
+ } else {
+ precision = getDefaultPrecision();
+ scale = getDefaultScale();
+ }
+ result = new DataType(typeName, precision, scale);
+ } else if(tokens.matches(OracleDataTypes.DTYPE_INTERVAL_YEAR)) {
+ //INTERVAL YEAR (year_precision) TO MONTH
+
+ } else if(tokens.matches(OracleDataTypes.DTYPE_INTERVAL_DAY)) {
+ //INTERVAL DAY (day_precision) TO SECOND (fractional_seconds_precision)
+ }
+
+ if( result == null ) {
+ result = super.parseCustomType(tokens);
+ }
+
+ return result;
+ }
+
+ /**
+ * Because Oracle has an additional option on the CHAR datatype, we need to override the super method, check
+ * for CHAR type and parse, else call super.parseCharStringType().
+ *
+ * {@inheritDoc}
+ *
+ * @see org.jboss.dna.sequencer.ddl.datatype.DataTypeParser#parseCharStringType(org.jboss.dna.sequencer.ddl.DdlTokenStream)
+ */
+ @Override
+ protected DataType parseCharStringType(DdlTokenStream tokens)
+ throws ParsingException {
+ DataType result = null;
+
+ if( tokens.matches(OracleDataTypes.DTYPE_CHAR_ORACLE)) {
+ String typeName = tokens.consume();
+ // CHAR (size [BYTE | CHAR]) (i.e. CHAR (10 BYTE) )
+ int length = getDefaultLength();
+ if( tokens.matches('(')) {
+ tokens.consume('(');
+ length = parseInteger(tokens);
+ if( tokens.matchesAnyOf("BYTE", OracleDataTypes.DTYPE_CHAR_ORACLE) ) {
+ tokens.consume();
+ }
+ tokens.consume(')');
+ }
+ result = new DataType(typeName, length);
+ } else {
+ result = super.parseCharStringType(tokens);
+ }
+
+ return result;
+ }
+
+ /**
+ *
+ * {@inheritDoc}
+ *
+ * @see org.jboss.dna.sequencer.ddl.datatype.DataTypeParser#isCustomDataType(org.jboss.dna.sequencer.ddl.DdlTokenStream)
+ */
+ @Override
+ protected boolean isCustomDataType(DdlTokenStream tokens)
+ throws ParsingException {
+ for( String[] stmt : oracleDataTypeStrings ) {
+ if( tokens.matches(stmt) ) return true;
+ }
+
+ return false;
+ }
+
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.jboss.dna.sequencer.ddl.StandardDdlParser#getDataTypeStartWords()
+ */
+ @Override
+ protected List<String> getCustomDataTypeStartWords() {
+ return OracleDataTypes.CUSTOM_DATATYPE_START_WORDS;
+ }
+}
Property changes on: branches/ddl_sequencer/extensions/dna-sequencer-ddl/src/main/java/org/jboss/dna/sequencer/ddl/dialect/oracle/OracleDdlParser.java
___________________________________________________________________
Name: svn:mime-type
+ text/plain
Added: branches/ddl_sequencer/extensions/dna-sequencer-ddl/src/main/java/org/jboss/dna/sequencer/ddl/statement/AlterTable.java
===================================================================
--- branches/ddl_sequencer/extensions/dna-sequencer-ddl/src/main/java/org/jboss/dna/sequencer/ddl/statement/AlterTable.java (rev 0)
+++ branches/ddl_sequencer/extensions/dna-sequencer-ddl/src/main/java/org/jboss/dna/sequencer/ddl/statement/AlterTable.java 2009-10-02 16:13:40 UTC (rev 1280)
@@ -0,0 +1,66 @@
+package org.jboss.dna.sequencer.ddl.statement;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+
+public class AlterTable extends Table {
+
+ private List<String> droppedColumnNames = new ArrayList<String>();
+ private HashMap<String, String> renamedColumns = new HashMap<String, String>();
+ private List<Column> modifiedColumns = new ArrayList<Column>();
+
+ private String actionValue = null;
+
+ public AlterTable(String name) {
+ super(name);
+ // TODO Auto-generated constructor stub
+ setType("ALTER TABLE");
+ }
+
+ public List<String> getDroppedColumnNames() {
+ return droppedColumnNames;
+ }
+
+ public void addDroppedColumnName(String name) {
+ this.droppedColumnNames.add(name);
+ }
+
+ public void addRenamedColumn(String oldName, String newName) {
+ renamedColumns.put(oldName, newName);
+ }
+
+ public HashMap<String, String> getRenamedColumnsMap() {
+ return renamedColumns;
+ }
+
+ public void addModifiedColumn(Column modifiedColumn) {
+ this.modifiedColumns.add(modifiedColumn);
+ }
+
+ public List<Column> getModifiedColumns() {
+ return this.modifiedColumns;
+ }
+
+ /**
+ * @return actionValue
+ */
+ public String getActionValue() {
+ return actionValue;
+ }
+
+ /**
+ * @param actionValue Sets actionValue to the specified value.
+ */
+ public void setActionValue(String actionValue) {
+ this.actionValue = actionValue;
+ }
+
+ @Override
+ public String toString() {
+ StringBuffer result = new StringBuffer(100);
+ result.append("AlterTable()").append(" ").append(getName());
+
+ return result.toString();
+ }
+}
Property changes on: branches/ddl_sequencer/extensions/dna-sequencer-ddl/src/main/java/org/jboss/dna/sequencer/ddl/statement/AlterTable.java
___________________________________________________________________
Name: svn:mime-type
+ text/plain
Added: branches/ddl_sequencer/extensions/dna-sequencer-ddl/src/main/java/org/jboss/dna/sequencer/ddl/statement/Column.java
===================================================================
--- branches/ddl_sequencer/extensions/dna-sequencer-ddl/src/main/java/org/jboss/dna/sequencer/ddl/statement/Column.java (rev 0)
+++ branches/ddl_sequencer/extensions/dna-sequencer-ddl/src/main/java/org/jboss/dna/sequencer/ddl/statement/Column.java 2009-10-02 16:13:40 UTC (rev 1280)
@@ -0,0 +1,88 @@
+package org.jboss.dna.sequencer.ddl.statement;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.jboss.dna.sequencer.ddl.datatype.DataType;
+
+public class Column extends TableElement {
+ private String name = null;
+ private DataType dataType = null;
+ private String defaultValue = null;
+ private String nullable = DEFAULT_NULLABLE;
+ private List<TableConstraint> constraints = new ArrayList<TableConstraint>();
+ private Table parentTable = null;
+
+ public static final String DEFAULT_NULLABLE = "NULL";
+
+
+ public Column(String name, DataType dataType) {
+ super();
+ this.name = name;
+ this.dataType = dataType;
+ }
+
+ public Column(String name, DataType dataType, Table parent) {
+ super();
+ this.name = name;
+ this.dataType = dataType;
+ this.parentTable = parent;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public DataType getDataType() {
+ return dataType;
+ }
+
+ public void setDataType(DataType dataType) {
+ this.dataType = dataType;
+ }
+
+ public String getDefaultValue() {
+ return defaultValue;
+ }
+
+ public void setDefaultValue(String defaultValue) {
+ this.defaultValue = defaultValue;
+ }
+
+ public String getNullable() {
+ return nullable;
+ }
+
+ public void setNullable(String nullable) {
+ this.nullable = nullable;
+ }
+
+ public void addConstraint(TableConstraint constraint) {
+ constraints.add(constraint);
+ }
+
+ public List<TableConstraint> getConstraints(){
+ return this.constraints;
+ }
+
+ @Override
+ public String toString() {
+ StringBuffer result = new StringBuffer(100);
+ result.append("Column()").append(" ").append(name);
+
+ return result.toString();
+ }
+
+ public Table getParentTable() {
+ return parentTable;
+ }
+
+ public void setParentTable(Table parentTable) {
+ this.parentTable = parentTable;
+ }
+
+}
Property changes on: branches/ddl_sequencer/extensions/dna-sequencer-ddl/src/main/java/org/jboss/dna/sequencer/ddl/statement/Column.java
___________________________________________________________________
Name: svn:mime-type
+ text/plain
Added: branches/ddl_sequencer/extensions/dna-sequencer-ddl/src/main/java/org/jboss/dna/sequencer/ddl/statement/ForeignKeyReference.java
===================================================================
--- branches/ddl_sequencer/extensions/dna-sequencer-ddl/src/main/java/org/jboss/dna/sequencer/ddl/statement/ForeignKeyReference.java (rev 0)
+++ branches/ddl_sequencer/extensions/dna-sequencer-ddl/src/main/java/org/jboss/dna/sequencer/ddl/statement/ForeignKeyReference.java 2009-10-02 16:13:40 UTC (rev 1280)
@@ -0,0 +1,35 @@
+package org.jboss.dna.sequencer.ddl.statement;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class ForeignKeyReference extends TableConstraint {
+ private String referencedTablename = null;
+ private List<String> referencedColumnNameList = null;
+
+
+ public ForeignKeyReference(int type, String name, List<String> columnNameList) {
+ super(type, name, columnNameList);
+ // TODO Auto-generated constructor stub
+ }
+
+
+ public String getReferencedTablename() {
+ return referencedTablename;
+ }
+
+
+ public void setReferencedTablename(String referencedTablename) {
+ this.referencedTablename = referencedTablename;
+ }
+
+
+ public List<String> getReferencedColumnNameList() {
+ return referencedColumnNameList;
+ }
+
+
+ public void setReferencedColumnNameList(List<String> referencedColumnNameList) {
+ this.referencedColumnNameList = new ArrayList<String>(referencedColumnNameList);
+ }
+}
Property changes on: branches/ddl_sequencer/extensions/dna-sequencer-ddl/src/main/java/org/jboss/dna/sequencer/ddl/statement/ForeignKeyReference.java
___________________________________________________________________
Name: svn:mime-type
+ text/plain
Added: branches/ddl_sequencer/extensions/dna-sequencer-ddl/src/main/java/org/jboss/dna/sequencer/ddl/statement/Index.java
===================================================================
--- branches/ddl_sequencer/extensions/dna-sequencer-ddl/src/main/java/org/jboss/dna/sequencer/ddl/statement/Index.java (rev 0)
+++ branches/ddl_sequencer/extensions/dna-sequencer-ddl/src/main/java/org/jboss/dna/sequencer/ddl/statement/Index.java 2009-10-02 16:13:40 UTC (rev 1280)
@@ -0,0 +1,54 @@
+package org.jboss.dna.sequencer.ddl.statement;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class Index extends TypedStatement {
+
+ private boolean isUnique = false;
+ private String tableName = null;
+ private List<String> columnNames = new ArrayList<String>();
+
+ public Index(String name, String tableName, List<String> columnNames) {
+ super();
+ setName(name);
+ setType("CREATE INDEX");
+ this.tableName = tableName;
+ this.columnNames.addAll(columnNames);
+ }
+
+
+ public void addColumn(String column) {
+ columnNames.add(column);
+ }
+
+ public List<String> getColumns() {
+ return this.columnNames;
+ }
+
+ @Override
+ public String toString() {
+ StringBuffer result = new StringBuffer(100);
+ result.append("Index()").append(" ").append(getName());
+
+ return result.toString();
+ }
+
+ public boolean isUnique() {
+ return isUnique;
+ }
+
+ public void setUnique(boolean isUnique) {
+ this.isUnique = isUnique;
+ }
+
+
+ public String getTableName() {
+ return tableName;
+ }
+
+
+ public void setTableName(String tableName) {
+ this.tableName = tableName;
+ }
+}
Property changes on: branches/ddl_sequencer/extensions/dna-sequencer-ddl/src/main/java/org/jboss/dna/sequencer/ddl/statement/Index.java
___________________________________________________________________
Name: svn:mime-type
+ text/plain
Added: branches/ddl_sequencer/extensions/dna-sequencer-ddl/src/main/java/org/jboss/dna/sequencer/ddl/statement/Statement.java
===================================================================
--- branches/ddl_sequencer/extensions/dna-sequencer-ddl/src/main/java/org/jboss/dna/sequencer/ddl/statement/Statement.java (rev 0)
+++ branches/ddl_sequencer/extensions/dna-sequencer-ddl/src/main/java/org/jboss/dna/sequencer/ddl/statement/Statement.java 2009-10-02 16:13:40 UTC (rev 1280)
@@ -0,0 +1,18 @@
+package org.jboss.dna.sequencer.ddl.statement;
+
+public interface Statement {
+ static final String UKNOWN_TYPE = "UNKNOWN";
+
+ String getType();
+
+ String getValue();
+
+ String getName();
+
+
+ void setType(String type);
+
+ void setValue(String value);
+
+ void setName(String name);
+}
Property changes on: branches/ddl_sequencer/extensions/dna-sequencer-ddl/src/main/java/org/jboss/dna/sequencer/ddl/statement/Statement.java
___________________________________________________________________
Name: svn:mime-type
+ text/plain
Added: branches/ddl_sequencer/extensions/dna-sequencer-ddl/src/main/java/org/jboss/dna/sequencer/ddl/statement/Table.java
===================================================================
--- branches/ddl_sequencer/extensions/dna-sequencer-ddl/src/main/java/org/jboss/dna/sequencer/ddl/statement/Table.java (rev 0)
+++ branches/ddl_sequencer/extensions/dna-sequencer-ddl/src/main/java/org/jboss/dna/sequencer/ddl/statement/Table.java 2009-10-02 16:13:40 UTC (rev 1280)
@@ -0,0 +1,41 @@
+package org.jboss.dna.sequencer.ddl.statement;
+
+import java.util.ArrayList;
+import java.util.List;
+
+
+public class Table extends TypedStatement {
+ private List<TableElement> columns = new ArrayList<TableElement>();
+ private List<TableElement> constraints = new ArrayList<TableElement>();
+
+ public Table(String name) {
+ super();
+ setName(name);
+ setType("CREATE TABLE");
+ setValue(null);
+ }
+
+ public void addColumn(TableElement column) {
+ columns.add(column);
+ }
+
+ public void addConstraint(TableElement tableConstraint) {
+ constraints.add(tableConstraint);
+ }
+
+ public List<TableElement> getColumns() {
+ return this.columns;
+ }
+
+ public List<TableElement> getConstraints() {
+ return this.constraints;
+ }
+
+ @Override
+ public String toString() {
+ StringBuffer result = new StringBuffer(100);
+ result.append("Table()").append(" ").append(getName());
+
+ return result.toString();
+ }
+}
Property changes on: branches/ddl_sequencer/extensions/dna-sequencer-ddl/src/main/java/org/jboss/dna/sequencer/ddl/statement/Table.java
___________________________________________________________________
Name: svn:mime-type
+ text/plain
Added: branches/ddl_sequencer/extensions/dna-sequencer-ddl/src/main/java/org/jboss/dna/sequencer/ddl/statement/TableConstraint.java
===================================================================
--- branches/ddl_sequencer/extensions/dna-sequencer-ddl/src/main/java/org/jboss/dna/sequencer/ddl/statement/TableConstraint.java (rev 0)
+++ branches/ddl_sequencer/extensions/dna-sequencer-ddl/src/main/java/org/jboss/dna/sequencer/ddl/statement/TableConstraint.java 2009-10-02 16:13:40 UTC (rev 1280)
@@ -0,0 +1,52 @@
+package org.jboss.dna.sequencer.ddl.statement;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class TableConstraint extends TableElement {
+ private int type = 0;
+ private String name = null;
+
+ private List<String> columnNameList = new ArrayList<String>();
+
+ public TableConstraint(int type, String name, List<String> columnNameList) {
+ super();
+ this.type = type;
+ this.name = name;
+ this.columnNameList.addAll(columnNameList);
+ }
+
+ public int getType() {
+ return type;
+ }
+
+ public void setType(int type) {
+ this.type = type;
+ }
+
+ public List<String> getColumnNameList() {
+ return columnNameList;
+ }
+
+ /**
+ * @return name
+ */
+ public String getName() {
+ return name;
+ }
+
+ /**
+ * @param name Sets name to the specified value.
+ */
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ @Override
+ public String toString() {
+ StringBuffer result = new StringBuffer(100);
+ result.append("TableConstraint()").append(" ").append(name);
+
+ return result.toString();
+ }
+}
Property changes on: branches/ddl_sequencer/extensions/dna-sequencer-ddl/src/main/java/org/jboss/dna/sequencer/ddl/statement/TableConstraint.java
___________________________________________________________________
Name: svn:mime-type
+ text/plain
Added: branches/ddl_sequencer/extensions/dna-sequencer-ddl/src/main/java/org/jboss/dna/sequencer/ddl/statement/TableElement.java
===================================================================
--- branches/ddl_sequencer/extensions/dna-sequencer-ddl/src/main/java/org/jboss/dna/sequencer/ddl/statement/TableElement.java (rev 0)
+++ branches/ddl_sequencer/extensions/dna-sequencer-ddl/src/main/java/org/jboss/dna/sequencer/ddl/statement/TableElement.java 2009-10-02 16:13:40 UTC (rev 1280)
@@ -0,0 +1,5 @@
+package org.jboss.dna.sequencer.ddl.statement;
+
+public abstract class TableElement {
+
+}
Property changes on: branches/ddl_sequencer/extensions/dna-sequencer-ddl/src/main/java/org/jboss/dna/sequencer/ddl/statement/TableElement.java
___________________________________________________________________
Name: svn:mime-type
+ text/plain
Added: branches/ddl_sequencer/extensions/dna-sequencer-ddl/src/main/java/org/jboss/dna/sequencer/ddl/statement/TypedStatement.java
===================================================================
--- branches/ddl_sequencer/extensions/dna-sequencer-ddl/src/main/java/org/jboss/dna/sequencer/ddl/statement/TypedStatement.java (rev 0)
+++ branches/ddl_sequencer/extensions/dna-sequencer-ddl/src/main/java/org/jboss/dna/sequencer/ddl/statement/TypedStatement.java 2009-10-02 16:13:40 UTC (rev 1280)
@@ -0,0 +1,39 @@
+package org.jboss.dna.sequencer.ddl.statement;
+
+public class TypedStatement implements Statement {
+ private String name = null;
+ private String type = Statement.UKNOWN_TYPE;
+ private String value = null;
+
+ public String getName() {
+ return name;
+ }
+
+ public String getType() {
+ return type;
+ }
+
+ public String getValue() {
+ return value;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public void setType(String type) {
+ this.type = type;
+ }
+
+ public void setValue(String value) {
+ this.value = value;
+ }
+
+ @Override
+ public String toString() {
+ StringBuffer result = new StringBuffer(100);
+ result.append(getType()).append(" NAME = ").append(getName());
+
+ return result.toString();
+ }
+}
Property changes on: branches/ddl_sequencer/extensions/dna-sequencer-ddl/src/main/java/org/jboss/dna/sequencer/ddl/statement/TypedStatement.java
___________________________________________________________________
Name: svn:mime-type
+ text/plain
Added: branches/ddl_sequencer/extensions/dna-sequencer-ddl/src/test/java/org/jboss/dna/sequencer/ddl/datatype/DataTypeParserTest.java
===================================================================
--- branches/ddl_sequencer/extensions/dna-sequencer-ddl/src/test/java/org/jboss/dna/sequencer/ddl/datatype/DataTypeParserTest.java (rev 0)
+++ branches/ddl_sequencer/extensions/dna-sequencer-ddl/src/test/java/org/jboss/dna/sequencer/ddl/datatype/DataTypeParserTest.java 2009-10-02 16:13:40 UTC (rev 1280)
@@ -0,0 +1,746 @@
+package org.jboss.dna.sequencer.ddl.datatype;
+
+import org.jboss.dna.common.text.ParsingException;
+import org.jboss.dna.sequencer.ddl.DdlConstants;
+import org.jboss.dna.sequencer.ddl.DdlTokenStream;
+
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+public class DataTypeParserTest implements DdlConstants {
+ private DataTypeParser parser;
+
+
+
+ @Before
+ public void beforeEach() {
+ parser = new DataTypeParser();
+ }
+
+ private DdlTokenStream getTokens(String content) {
+ DdlTokenStream tokens = new DdlTokenStream(content, DdlTokenStream.ddlTokenizer(false), false);
+
+ tokens.start();
+
+ return tokens;
+ }
+
+ private String getDataTypeString(String[] input) {
+ StringBuffer sb = new StringBuffer();
+
+ for(int i=0; i<input.length; i++ ) {
+ if( i>0 ) {
+ sb.append(SPACE);
+ }
+ sb.append(input[i]);
+ }
+
+ return sb.toString();
+ }
+
+ /* ===========================================================================================================================
+ * UTILITY METHODS
+ * ==========================================================================================================================
+ */
+
+ @Test
+ public void shouldParseBracketedInteger() {
+ String content = "(255)";
+ DdlTokenStream tokens = getTokens(content);
+ int value = parser.parseBracketedInteger(tokens);
+
+ Assert.assertEquals("DataType length is not correct", 255, value);
+ }
+
+ @Test
+ public void shouldParseKMGInteger() {
+ String content = "1000M";
+ DdlTokenStream tokens = getTokens(content);
+
+ int value = parser.parseInteger(tokens);
+ Assert.assertEquals("DataType length is not correct", 1000, value);
+
+ content = "1000G";
+ tokens = getTokens(content);
+ value = parser.parseInteger(tokens);
+
+ Assert.assertEquals("DataType length is not correct", 1000, value);
+
+ content = "1000K";
+ tokens = getTokens(content);
+ value = parser.parseInteger(tokens);
+
+ Assert.assertEquals("DataType length is not correct", 1000, value);
+
+ content = "(1000M)";
+ tokens = getTokens(content);
+ value = parser.parseBracketedInteger(tokens);
+
+ Assert.assertEquals("DataType length is not correct", 1000, value);
+
+ content = "(1000G)";
+ tokens = getTokens(content);
+ value = parser.parseBracketedInteger(tokens);
+
+ Assert.assertEquals("DataType length is not correct", 1000, value);
+
+ content = "(1000K)";
+ tokens = getTokens(content);
+ value = parser.parseBracketedInteger(tokens);
+
+ Assert.assertEquals("DataType length is not correct", 1000, value);
+ }
+
+ /* ===========================================================================================================================
+ * CHARACTER STRING TYPE
+ * ==========================================================================================================================
+ <character string type> ::=
+ CHARACTER [ <left paren> <length> <right paren> ]
+ | CHAR [ <left paren> <length> <right paren> ]
+ | CHARACTER VARYING <left paren> <length> <right paren>
+ | CHAR VARYING <left paren> <length> <right paren>
+ | VARCHAR <left paren> <length> <right paren>
+ */
+
+ @Test
+ public void shouldParseCHAR() {
+ String typeString = getDataTypeString(DataTypes.DTYPE_CHAR);
+ String content = typeString;
+
+ DdlTokenStream tokens = getTokens(content);
+
+ DataType dType = parser.parse(tokens);
+
+ Assert.assertNotNull("DataType was NOT found for Type = " + typeString, dType);
+ Assert.assertEquals("Wrong DataType found", typeString, dType.getName());
+
+ content = typeString + " (255)";
+ tokens = getTokens(content);
+
+ dType = parser.parse(tokens);
+
+ Assert.assertNotNull("DataType was NOT found for Type = " + typeString, dType);
+ Assert.assertEquals("Wrong DataType found", typeString, dType.getName());
+ Assert.assertEquals("DataType length is not correct", 255, dType.getLength());
+ }
+
+ @Test
+ public void shouldParseCHARACTER() {
+ String typeString = getDataTypeString(DataTypes.DTYPE_CHARACTER);
+ String content = typeString;
+
+ DdlTokenStream tokens = getTokens(content);
+
+ DataType dType = parser.parse(tokens);
+
+ Assert.assertNotNull("DataType was NOT found for Type = " + typeString, dType);
+ Assert.assertEquals("Wrong DataType found", typeString, dType.getName());
+
+ content = typeString + " (255)";
+ tokens = getTokens(content);
+
+ dType = parser.parse(tokens);
+
+ Assert.assertNotNull("DataType was NOT found for Type = " + typeString, dType);
+ Assert.assertEquals("Wrong DataType found", typeString, dType.getName());
+ Assert.assertEquals("DataType length is not correct", 255, dType.getLength());
+ }
+
+ @Test
+ public void shouldParseCHAR_VARYING() {
+ String typeString = getDataTypeString(DataTypes.DTYPE_CHAR_VARYING);
+ String content = typeString + " (255)";
+
+ DdlTokenStream tokens = getTokens(content);
+
+ DataType dType = parser.parse(tokens);
+
+ Assert.assertNotNull("DataType was NOT found for Type = " + typeString, dType);
+ Assert.assertEquals("Wrong DataType found", typeString, dType.getName());
+ Assert.assertEquals("DataType length is not correct", 255, dType.getLength());
+ }
+
+ @Test
+ public void shouldParseCHARACTER_VARYING() {
+ String typeString = getDataTypeString(DataTypes.DTYPE_CHARACTER_VARYING);
+ String content = typeString + " (255)";
+
+ DdlTokenStream tokens = getTokens(content);
+
+ DataType dType = parser.parse(tokens);
+
+ Assert.assertNotNull("DataType was NOT found for Type = " + typeString, dType);
+ Assert.assertEquals("Wrong DataType found", typeString, dType.getName());
+ Assert.assertEquals("DataType length is not correct", 255, dType.getLength());
+ }
+
+ @Test
+ public void shouldParseVARCHAR() {
+ String typeString = getDataTypeString(DataTypes.DTYPE_VARCHAR);
+ String content = typeString + " (255)";
+
+ DdlTokenStream tokens = getTokens(content);
+
+ DataType dType = parser.parse(tokens);
+
+ Assert.assertNotNull("DataType was NOT found for Type = " + typeString, dType);
+ Assert.assertEquals("Wrong DataType found", typeString, dType.getName());
+ Assert.assertEquals("DataType length is not correct", 255, dType.getLength());
+
+ content = typeString;
+ tokens = getTokens(content);
+ dType = null;
+ try {
+ dType = parser.parse(tokens);
+ } catch (ParsingException e) {
+ // Expect exception
+ }
+
+ Assert.assertNull("DataType should NOT have been found for Type = " + content, dType);
+ }
+
+ /* ===========================================================================================================================
+ * NATIONAL CHARACTER STRING TYPE
+ * ==========================================================================================================================
+ *
+ *
+ <national character string type> ::=
+ NATIONAL CHARACTER [ <left paren> <length> <right paren> ]
+ | NATIONAL CHAR [ <left paren> <length> <right paren> ]
+ | NCHAR [ <left paren> <length> <right paren> ]
+ | NATIONAL CHARACTER VARYING <left paren> <length> <right paren>
+ | NATIONAL CHAR VARYING <left paren> <length> <right paren>
+ | NCHAR VARYING <left paren> <length> <right paren>
+
+ *
+ *
+ */
+ @Test
+ public void shouldParseNATIONAL_CHAR() {
+ String typeString = getDataTypeString(DataTypes.DTYPE_NATIONAL_CHAR);
+ String content = typeString;
+
+ DdlTokenStream tokens = getTokens(content);
+
+ DataType dType = parser.parse(tokens);
+
+ Assert.assertNotNull("DataType was NOT found for Type = " + typeString, dType);
+ Assert.assertEquals("Wrong DataType found", typeString, dType.getName());
+
+ content = typeString + " (255)";
+ tokens = getTokens(content);
+
+ dType = parser.parse(tokens);
+
+ Assert.assertNotNull("DataType was NOT found for Type = " + typeString, dType);
+ Assert.assertEquals("Wrong DataType found", typeString, dType.getName());
+ Assert.assertEquals("DataType length is not correct", 255, dType.getLength());
+ }
+
+ @Test
+ public void shouldParseNATIONAL_CHARACTER() {
+ String typeString = getDataTypeString(DataTypes.DTYPE_NATIONAL_CHARACTER);
+ String content = typeString;
+
+ DdlTokenStream tokens = getTokens(content);
+
+ DataType dType = parser.parse(tokens);
+
+ Assert.assertNotNull("DataType was NOT found for Type = " + typeString, dType);
+ Assert.assertEquals("Wrong DataType found", typeString, dType.getName());
+
+ content = typeString + " (255)";
+ tokens = getTokens(content);
+
+ dType = parser.parse(tokens);
+
+ Assert.assertNotNull("DataType was NOT found for Type = " + typeString, dType);
+ Assert.assertEquals("Wrong DataType found", typeString, dType.getName());
+ Assert.assertEquals("DataType length is not correct", 255, dType.getLength());
+ }
+
+ @Test
+ public void shouldParseNATIONAL_CHAR_VARYING() {
+ String typeString = getDataTypeString(DataTypes.DTYPE_NATIONAL_CHAR_VARYING);
+ String content = typeString + " (255)";
+
+ DdlTokenStream tokens = getTokens(content);
+
+ DataType dType = parser.parse(tokens);
+
+ Assert.assertNotNull("DataType was NOT found for Type = " + typeString, dType);
+ Assert.assertEquals("Wrong DataType found", typeString, dType.getName());
+ Assert.assertEquals("DataType length is not correct", 255, dType.getLength());
+ }
+
+ @Test
+ public void shouldParseNATIONAL_CHARACTER_VARYING() {
+ String typeString = getDataTypeString(DataTypes.DTYPE_NATIONAL_CHARACTER_VARYING);
+ String content = typeString + " (255)";
+
+ DdlTokenStream tokens = getTokens(content);
+
+ DataType dType = parser.parse(tokens);
+
+ Assert.assertNotNull("DataType was NOT found for Type = " + typeString, dType);
+ Assert.assertEquals("Wrong DataType found", typeString, dType.getName());
+ Assert.assertEquals("DataType length is not correct", 255, dType.getLength());
+ }
+
+ @Test
+ public void shouldParseNCHAR_VARYING() {
+ String typeString = getDataTypeString(DataTypes.DTYPE_NCHAR_VARYING);
+ String content = typeString + " (255)";
+
+ DdlTokenStream tokens = getTokens(content);
+
+ DataType dType = parser.parse(tokens);
+
+ Assert.assertNotNull("DataType was NOT found for Type = " + typeString, dType);
+ Assert.assertEquals("Wrong DataType found", typeString, dType.getName());
+ Assert.assertEquals("DataType length is not correct", 255, dType.getLength());
+
+ content = typeString;
+ tokens = getTokens(content);
+ dType = null;
+ try {
+ dType = parser.parse(tokens);
+ } catch (ParsingException e) {
+ // Expect exception
+ }
+
+ Assert.assertNull("DataType should NOT have been found for Type = " + content, dType);
+ }
+
+
+ /* ===========================================================================================================================
+ * NATIONAL CHARACTER STRING TYPE
+ * ==========================================================================================================================
+ *
+ <bit string type> ::=
+ BIT [ <left paren> <length> <right paren> ]
+ | BIT VARYING <left paren> <length> <right paren>
+ *
+ */
+
+ @Test
+ public void shouldParseBIT() {
+ String typeString = getDataTypeString(DataTypes.DTYPE_BIT);
+ String content = typeString;
+
+ DdlTokenStream tokens = getTokens(content);
+
+ DataType dType = parser.parse(tokens);
+
+ Assert.assertNotNull("DataType was NOT found for Type = " + typeString, dType);
+ Assert.assertEquals("Wrong DataType found", typeString, dType.getName());
+ }
+
+ @Test
+ public void shouldParseBITWithLength() {
+ String typeString = getDataTypeString(DataTypes.DTYPE_BIT);
+ String content = typeString + " (255)";
+
+ DdlTokenStream tokens = getTokens(content);
+
+ DataType dType = parser.parse(tokens);
+
+ Assert.assertNotNull("DataType was NOT found for Type = " + typeString, dType);
+ Assert.assertEquals("Wrong DataType found", typeString, dType.getName());
+ Assert.assertEquals("DataType length is not correct", 255, dType.getLength());
+ }
+
+ @Test
+ public void shouldParseBIT_VARYINGWithLength() {
+ String typeString = getDataTypeString(DataTypes.DTYPE_BIT_VARYING);
+ String content = typeString + " (255)";
+
+ DdlTokenStream tokens = getTokens(content);
+
+ DataType dType = parser.parse(tokens);
+
+ Assert.assertNotNull("DataType was NOT found for Type = " + typeString, dType);
+ Assert.assertEquals("Wrong DataType found", typeString, dType.getName());
+ Assert.assertEquals("DataType length is not correct", 255, dType.getLength());
+
+ content = typeString;
+ tokens = getTokens(content);
+ dType = null;
+ try {
+ dType = parser.parse(tokens);
+ } catch (ParsingException e) {
+ // Expect exception
+ }
+
+ Assert.assertNull("DataType should NOT have been found for Type = " + content, dType);
+ }
+
+ /* ===========================================================================================================================
+ * EXACT NUMERIC TYPE
+ * ==========================================================================================================================
+ <exact numeric type> ::=
+ NUMERIC [ <left paren> <precision> [ <comma> <scale> ] <right paren> ]
+ | DECIMAL [ <left paren> <precision> [ <comma> <scale> ] <right paren> ]
+ | DEC [ <left paren> <precision> [ <comma> <scale> ] <right paren> ]
+ | INTEGER
+ | INT
+ | SMALLINT
+ *
+ */
+
+ @Test
+ public void shouldNotParseXXXXXXTYPE() {
+ String typeString = "XXXXXXTYPE";
+ String content = typeString;
+
+ DdlTokenStream tokens = getTokens(content);
+
+
+ DataType dType = null;
+ try {
+ dType = parser.parse(tokens);
+ } catch (ParsingException e) {
+ // Expect exception
+ }
+
+ Assert.assertNull("DataType should NOT have been found for Type = " + typeString, dType);
+ }
+
+ @Test
+ public void shouldParseINT() {
+ String typeString = getDataTypeString(DataTypes.DTYPE_INT);
+ String content = typeString;
+
+ DdlTokenStream tokens = getTokens(content);
+
+ DataType dType = parser.parse(tokens);
+
+ Assert.assertNotNull("DataType was NOT found for Type = " + typeString, dType);
+ Assert.assertEquals("Wrong DataType found", typeString, dType.getName());
+ }
+
+ @Test
+ public void shouldParseINTEGER() {
+ String typeString = getDataTypeString(DataTypes.DTYPE_INTEGER);
+ String content = typeString;
+
+ DdlTokenStream tokens = getTokens(content);
+
+ DataType dType = parser.parse(tokens);
+
+ Assert.assertNotNull("DataType was NOT found for Type = " + typeString, dType);
+ Assert.assertEquals("Wrong DataType found", typeString, dType.getName());
+ }
+
+ @Test
+ public void shouldParseSMALLINT() {
+ String typeString = getDataTypeString(DataTypes.DTYPE_SMALLINT);
+ String content = typeString;
+
+ DdlTokenStream tokens = getTokens(content);
+
+ DataType dType = parser.parse(tokens);
+
+ Assert.assertNotNull("DataType was NOT found for Type = " + typeString, dType);
+ Assert.assertEquals("Wrong DataType found", typeString, dType.getName());
+ }
+
+ @Test
+ public void shouldParseNUMERIC() {
+ String typeString = getDataTypeString(DataTypes.DTYPE_NUMERIC);
+ String content = typeString;
+
+ DdlTokenStream tokens = getTokens(content);
+
+ DataType dType = parser.parse(tokens);
+
+ Assert.assertNotNull("DataType was NOT found for Type = " + typeString, dType);
+ Assert.assertEquals("Wrong DataType found", typeString, dType.getName());
+
+ content = typeString + " (5)";
+ tokens = getTokens(content);
+ dType = parser.parse(tokens);
+ Assert.assertNotNull("DataType was NOT found for Type = " + typeString, dType);
+ Assert.assertEquals("Wrong DataType found", typeString, dType.getName());
+ Assert.assertEquals("DataType length is not correct", 5, dType.getPrecision()); // PRECISION
+
+ content = typeString + " (5, 2)";
+ tokens = getTokens(content);
+ dType = parser.parse(tokens);
+ Assert.assertNotNull("DataType was NOT found for Type = " + typeString, dType);
+ Assert.assertEquals("Wrong DataType found", typeString, dType.getName());
+ Assert.assertEquals("DataType length is not correct", 5, dType.getPrecision()); // PRECISION
+ Assert.assertEquals("DataType length is not correct", 2, dType.getScale()); // SCALE
+
+
+ // MISSING COMMA
+ content = typeString + " (5 2)";
+ tokens = getTokens(content);
+ dType = null;
+ try {
+ dType = parser.parse(tokens);
+ } catch (ParsingException e) {
+ // Expect exception
+ }
+ Assert.assertNull("DataType should NOT have been found for Type = " + content, dType);
+
+
+ // INVALID Scale Integer
+ content = typeString + " (5 A)";
+ tokens = getTokens(content);
+ dType = null;
+ try {
+ dType = parser.parse(tokens);
+ } catch (ParsingException e) {
+ // Expect exception
+ }
+ Assert.assertNull("DataType should NOT have been found for Type = " + content, dType);
+ }
+
+
+ @Test
+ public void shouldParseDECIMAL() {
+ String typeString = getDataTypeString(DataTypes.DTYPE_DECIMAL);
+ String content = typeString;
+
+ DdlTokenStream tokens = getTokens(content);
+
+ DataType dType = parser.parse(tokens);
+
+ Assert.assertNotNull("DataType was NOT found for Type = " + typeString, dType);
+ Assert.assertEquals("Wrong DataType found", typeString, dType.getName());
+
+ content = typeString + " (5)";
+ tokens = getTokens(content);
+ dType = parser.parse(tokens);
+ Assert.assertNotNull("DataType was NOT found for Type = " + typeString, dType);
+ Assert.assertEquals("Wrong DataType found", typeString, dType.getName());
+ Assert.assertEquals("DataType length is not correct", 5, dType.getPrecision()); // PRECISION
+
+ content = typeString + " (5, 2)";
+ tokens = getTokens(content);
+ dType = parser.parse(tokens);
+ Assert.assertNotNull("DataType was NOT found for Type = " + typeString, dType);
+ Assert.assertEquals("Wrong DataType found", typeString, dType.getName());
+ Assert.assertEquals("DataType length is not correct", 5, dType.getPrecision()); // PRECISION
+ Assert.assertEquals("DataType length is not correct", 2, dType.getScale()); // SCALE
+
+ // MISSING COMMA
+ content = typeString + " (5 2)";
+ tokens = getTokens(content);
+ dType = null;
+ try {
+ dType = parser.parse(tokens);
+ } catch (ParsingException e) {
+ // Expect exception
+ }
+ Assert.assertNull("DataType should NOT have been found for Type = " + content, dType);
+
+
+ // INVALID Scale Integer
+ content = typeString + " (5 A)";
+ tokens = getTokens(content);
+ dType = null;
+ try {
+ dType = parser.parse(tokens);
+ } catch (ParsingException e) {
+ // Expect exception
+ }
+ Assert.assertNull("DataType should NOT have been found for Type = " + content, dType);
+ }
+
+
+ @Test
+ public void shouldParseDEC() {
+ String typeString = getDataTypeString(DataTypes.DTYPE_DEC);
+ String content = typeString;
+
+ DdlTokenStream tokens = getTokens(content);
+
+ DataType dType = parser.parse(tokens);
+
+ Assert.assertNotNull("DataType was NOT found for Type = " + typeString, dType);
+ Assert.assertEquals("Wrong DataType found", typeString, dType.getName());
+
+ content = typeString + " (5)";
+ tokens = getTokens(content);
+ dType = parser.parse(tokens);
+ Assert.assertNotNull("DataType was NOT found for Type = " + typeString, dType);
+ Assert.assertEquals("Wrong DataType found", typeString, dType.getName());
+ Assert.assertEquals("DataType length is not correct", 5, dType.getPrecision()); // PRECISION
+
+ content = typeString + " (5, 2)";
+ tokens = getTokens(content);
+ dType = parser.parse(tokens);
+ Assert.assertNotNull("DataType was NOT found for Type = " + typeString, dType);
+ Assert.assertEquals("Wrong DataType found", typeString, dType.getName());
+ Assert.assertEquals("DataType length is not correct", 5, dType.getPrecision()); // PRECISION
+ Assert.assertEquals("DataType length is not correct", 2, dType.getScale()); // SCALE
+
+
+ // MISSING COMMA
+ content = typeString + " (5 2)";
+ tokens = getTokens(content);
+ dType = null;
+ try {
+ dType = parser.parse(tokens);
+ } catch (ParsingException e) {
+ // Expect exception
+ }
+ Assert.assertNull("DataType should NOT have been found for Type = " + content, dType);
+
+
+ // INVALID Scale Integer
+ content = typeString + " (5 A)";
+ tokens = getTokens(content);
+ dType = null;
+ try {
+ dType = parser.parse(tokens);
+ } catch (ParsingException e) {
+ // Expect exception
+ }
+ Assert.assertNull("DataType should NOT have been found for Type = " + content, dType);
+ }
+
+
+ /* ===========================================================================================================================
+ * APPROXIMATE NUMERIC TYPE
+ * ==========================================================================================================================
+ *
+ <approximate numeric type> ::=
+ FLOAT [ <left paren> <precision> <right paren> ]
+ | REAL
+ | DOUBLE PRECISION
+ */
+
+
+
+ @Test
+ public void shouldParseFLOAT() {
+ String typeString = getDataTypeString(DataTypes.DTYPE_FLOAT);
+ String content = typeString;
+
+ DdlTokenStream tokens = getTokens(content);
+
+ DataType dType = parser.parse(tokens);
+
+ Assert.assertNotNull("DataType was NOT found for Type = " + typeString, dType);
+ Assert.assertEquals("Wrong DataType found", typeString, dType.getName());
+
+ content = typeString + " (5)";
+ tokens = getTokens(content);
+ dType = parser.parse(tokens);
+ Assert.assertNotNull("DataType was NOT found for Type = " + typeString, dType);
+ Assert.assertEquals("Wrong DataType found", typeString, dType.getName());
+ Assert.assertEquals("DataType length is not correct", 5, dType.getPrecision()); // PRECISION
+
+ // ADDED SCALE
+ content = typeString + " (5, 2)";
+ tokens = getTokens(content);
+ dType = null;
+ try {
+ dType = parser.parse(tokens);
+ } catch (ParsingException e) {
+ // Expect exception
+ }
+ Assert.assertNull("DataType should NOT have been found for Type = " + content, dType);
+
+ }
+
+ @Test
+ public void shouldParseREAL() {
+ String typeString = getDataTypeString(DataTypes.DTYPE_REAL);
+ String content = typeString;
+
+ DdlTokenStream tokens = getTokens(content);
+
+ DataType dType = parser.parse(tokens);
+
+ Assert.assertNotNull("DataType was NOT found for Type = " + typeString, dType);
+ Assert.assertEquals("Wrong DataType found", typeString, dType.getName());
+ }
+
+
+ @Test
+ public void shouldParseDOUBLE_PRECISION() {
+ String typeString = getDataTypeString(DataTypes.DTYPE_DOUBLE_PRECISION);
+ String content = typeString;
+
+ DdlTokenStream tokens = getTokens(content);
+
+ DataType dType = parser.parse(tokens);
+
+ Assert.assertNotNull("DataType was NOT found for Type = " + typeString, dType);
+ Assert.assertEquals("Wrong DataType found", typeString, dType.getName());
+ }
+
+ /* ===========================================================================================================================
+ * APPROXIMATE NUMERIC TYPE
+ * ==========================================================================================================================
+ *
+ <datetime type> ::=
+ DATE
+ | TIME [ <left paren> <time precision> <right paren> ] [ WITH TIME ZONE ]
+ | TIMESTAMP [ <left paren> <timestamp precision> <right paren> ] [ WITH TIME ZONE ]
+
+ NOTE: time precision & timestamp precision is an integer from 0 to 9
+ */
+
+ @Test
+ public void shouldParseDATE() {
+ String typeString = getDataTypeString(DataTypes.DTYPE_DATE);
+ String content = typeString;
+
+ DdlTokenStream tokens = getTokens(content);
+
+ DataType dType = parser.parse(tokens);
+
+ Assert.assertNotNull("DataType was NOT found for Type = " + typeString, dType);
+ Assert.assertEquals("Wrong DataType found", typeString, dType.getName());
+ }
+
+ @Test
+ public void shouldParseTIME() {
+ String typeString = getDataTypeString(DataTypes.DTYPE_TIME);
+ String content = typeString;
+
+ DdlTokenStream tokens = getTokens(content);
+
+ DataType dType = parser.parse(tokens);
+
+ Assert.assertNotNull("DataType was NOT found for Type = " + typeString, dType);
+ Assert.assertEquals("Wrong DataType found", typeString, dType.getName());
+
+
+ content = typeString + " (6)";
+ tokens = getTokens(content);
+ dType = parser.parse(tokens);
+
+ Assert.assertNotNull("DataType was NOT found for Type = " + typeString, dType);
+ Assert.assertEquals("Wrong DataType found", typeString, dType.getName());
+ Assert.assertEquals("DataType length is not correct", 6, dType.getPrecision());
+ }
+
+ @Test
+ public void shouldParseTIMESTAMP() {
+ String typeString = getDataTypeString(DataTypes.DTYPE_TIMESTAMP);
+ String content = typeString;
+
+ DdlTokenStream tokens = getTokens(content);
+
+ DataType dType = parser.parse(tokens);
+
+ Assert.assertNotNull("DataType was NOT found for Type = " + typeString, dType);
+ Assert.assertEquals("Wrong DataType found", typeString, dType.getName());
+
+
+ content = typeString + " (6)";
+ tokens = getTokens(content);
+ dType = parser.parse(tokens);
+
+ Assert.assertNotNull("DataType was NOT found for Type = " + typeString, dType);
+ Assert.assertEquals("Wrong DataType found", typeString, dType.getName());
+ Assert.assertEquals("DataType length is not correct", 6, dType.getPrecision());
+ }
+}
\ No newline at end of file
Property changes on: branches/ddl_sequencer/extensions/dna-sequencer-ddl/src/test/java/org/jboss/dna/sequencer/ddl/datatype/DataTypeParserTest.java
___________________________________________________________________
Name: svn:mime-type
+ text/plain
Added: branches/ddl_sequencer/extensions/dna-sequencer-ddl/src/test/java/org/jboss/dna/sequencer/ddl/dialect/DerbyDdlParserTest.java
===================================================================
--- branches/ddl_sequencer/extensions/dna-sequencer-ddl/src/test/java/org/jboss/dna/sequencer/ddl/dialect/DerbyDdlParserTest.java (rev 0)
+++ branches/ddl_sequencer/extensions/dna-sequencer-ddl/src/test/java/org/jboss/dna/sequencer/ddl/dialect/DerbyDdlParserTest.java 2009-10-02 16:13:40 UTC (rev 1280)
@@ -0,0 +1,107 @@
+package org.jboss.dna.sequencer.ddl.dialect;
+
+import static org.junit.Assert.assertEquals;
+
+import java.io.BufferedReader;
+import java.io.FileReader;
+import java.util.List;
+
+import org.jboss.dna.sequencer.ddl.StandardDdlParser;
+import org.jboss.dna.sequencer.ddl.dialect.DerbyDdlParser;
+import org.jboss.dna.sequencer.ddl.statement.Statement;
+import org.junit.Before;
+import org.junit.Test;
+
+public class DerbyDdlParserTest {
+ private StandardDdlParser parser;
+
+
+ public static final String DDL_FILE_PATH = "src/test/resources/ddl/";
+ public static final String MM_DDL_FILE_PATH = "src/test/resources/mmddl/";
+
+
+ @Before
+ public void beforeEach() {
+ parser = new DerbyDdlParser();
+ }
+
+ protected String getFileContent(String filePath) {
+ StringBuilder sb = new StringBuilder(1000);
+
+ System.out.println(" Getting Content for File = " + filePath);
+
+ if(filePath!=null && filePath.length() > 0){
+ FileReader fr=null;
+ BufferedReader in=null;
+
+ try{
+ fr=new FileReader(filePath);
+ in = new BufferedReader(fr);
+
+ int ch = in.read();
+
+ while( ch > -1 ) {
+ sb.append((char)ch);
+ ch = in.read();
+ }
+ }catch(Exception e){
+ System.out.print(e);
+ }
+ finally{
+ try{
+ fr.close();
+ }catch(java.io.IOException e){}
+ try{
+ in.close();
+ }catch(java.io.IOException e){}
+
+ }
+ }
+ return sb.toString();
+ }
+
+
+// @Test
+// public void shouldParseDerbyDDL() {
+// String content = getFileContent(DDL_FILE_PATH + "derby_test_create.ddl");
+//
+// List<Statement> stmts = parser.parse(content);
+//
+// assertEquals(744, stmts.size());
+//
+// System.out.println(" END PARSING. # Statements = " + stmts.size());
+//
+// }
+
+
+ @Test
+ public void shouldParseDeclareGlobaTemporaryTable() {
+ System.out.println("TEST: shouldParseDeclareGlobaTemporaryTable()");
+ String content = "declare global temporary table SESSION.t1(c11 int) not logged;";
+ parser.setDoUseTerminator(true);
+ List<Statement> stmts = parser.parse(content);
+ assertEquals("DECLARE", stmts.get(0).getType());
+ }
+
+ @Test
+ public void shouldParseAlterTableAlterColumnDefaultRealNumber() {
+ System.out.println("TEST: shouldParseAlterTableAlterColumnDefaultRealNumber()");
+ String content = "ALTER TABLE Employees ALTER COLUMN Salary DEFAULT 1000.0;";
+ parser.setDoUseTerminator(true);
+ List<Statement> stmts = parser.parse(content);
+ assertEquals("ALTER TABLE", stmts.get(0).getType());
+ }
+
+
+
+ @Test
+ public void shouldParseDerbyStatements() {
+ //System.out.println("TEST: shouldParseDerbyStatements()");
+ String content = getFileContent(DDL_FILE_PATH + "derby_test_statements.ddl");
+ parser.setDoUseTerminator(true);
+ List<Statement> stmts = parser.parse(content);
+ assertEquals(64, stmts.size());
+ System.out.println(" END PARSING. # Statements = " + stmts.size());
+
+ }
+}
\ No newline at end of file
Property changes on: branches/ddl_sequencer/extensions/dna-sequencer-ddl/src/test/java/org/jboss/dna/sequencer/ddl/dialect/DerbyDdlParserTest.java
___________________________________________________________________
Name: svn:mime-type
+ text/plain
Added: branches/ddl_sequencer/extensions/dna-sequencer-ddl/src/test/java/org/jboss/dna/sequencer/ddl/dialect/OracleDdlParserTest.java
===================================================================
--- branches/ddl_sequencer/extensions/dna-sequencer-ddl/src/test/java/org/jboss/dna/sequencer/ddl/dialect/OracleDdlParserTest.java (rev 0)
+++ branches/ddl_sequencer/extensions/dna-sequencer-ddl/src/test/java/org/jboss/dna/sequencer/ddl/dialect/OracleDdlParserTest.java 2009-10-02 16:13:40 UTC (rev 1280)
@@ -0,0 +1,192 @@
+package org.jboss.dna.sequencer.ddl.dialect;
+
+import static org.junit.Assert.assertEquals;
+
+import java.io.BufferedReader;
+import java.io.FileReader;
+import java.util.List;
+
+import org.jboss.dna.sequencer.ddl.DdlConstants;
+import org.jboss.dna.sequencer.ddl.StandardDdlParser;
+import org.jboss.dna.sequencer.ddl.dialect.oracle.OracleDdlParser;
+import org.jboss.dna.sequencer.ddl.statement.Statement;
+import org.junit.Before;
+import org.junit.Test;
+
+public class OracleDdlParserTest {
+ private StandardDdlParser parser;
+
+
+ public static final String DDL_FILE_PATH = "src/test/resources/ddl/";
+ public static final String MM_DDL_FILE_PATH = "src/test/resources/mmddl/";
+
+
+ @Before
+ public void beforeEach() {
+ parser = new OracleDdlParser();
+ }
+
+ protected String getFileContent(String filePath) {
+ StringBuilder sb = new StringBuilder(1000);
+
+ System.out.println(" Getting Content for File = " + filePath);
+
+ if(filePath!=null && filePath.length() > 0){
+ FileReader fr=null;
+ BufferedReader in=null;
+
+ try{
+ fr=new FileReader(filePath);
+ in = new BufferedReader(fr);
+
+ int ch = in.read();
+
+ while( ch > -1 ) {
+ sb.append((char)ch);
+ ch = in.read();
+ }
+ }catch(Exception e){
+ System.out.print(e);
+ }
+ finally{
+ try{
+ fr.close();
+ }catch(java.io.IOException e){}
+ try{
+ in.close();
+ }catch(java.io.IOException e){}
+
+ }
+ }
+ return sb.toString();
+ }
+
+// @Test
+// public void shouldParseOracleDDL() {
+// String content = getFileContent(DDL_FILE_PATH + "oracle_test_create.ddl");
+//
+// List<Statement> stmts = parser.parse(content);
+//
+// System.out.println(" END PARSING. # Statements = " + stmts.size());
+//
+// }
+
+ @Test
+ public void shouldParseCreateOrReplaceTrigger() {
+ System.out.println("TEST: shouldParseCreateOrReplaceTrigger()");
+ String content = "CREATE OR REPLACE TRIGGER drop_trigger" + DdlConstants.SPACE +
+ "BEFORE DROP ON hr.SCHEMA" + DdlConstants.SPACE +
+ "BEGIN" + DdlConstants.SPACE +
+ "RAISE_APPLICATION_ERROR ( num => -20000,msg => 'Cannot drop object');" + DdlConstants.SPACE +
+ "END;" + DdlConstants.SPACE + "/";
+ parser.setDoUseTerminator(true);
+ List<Statement> stmts = parser.parse(content);
+ System.out.println(" END PARSING. # Statements = " + stmts.size());
+ System.out.println(" VALUE STMT 1 = " + stmts.get(0).getValue());
+
+ }
+
+ @Test
+ public void shouldParseAnalyze() {
+ System.out.println("TEST: shouldParseAnalyze()");
+ String content = "ANALYZE TABLE customers VALIDATE STRUCTURE ONLINE;";
+ parser.setDoUseTerminator(true);
+ List<Statement> stmts = parser.parse(content);
+ assertEquals("ANALYZE", stmts.get(0).getType());
+ }
+
+ @Test
+ public void shouldParseRollbackToSavepoint() {
+ System.out.println("TEST: shouldParseRollbackToSavepoint()");
+ String content = "ROLLBACK TO SAVEPOINT banda_sal;";
+ parser.setDoUseTerminator(true);
+ List<Statement> stmts = parser.parse(content);
+ assertEquals("ROLLBACK TO SAVEPOINT", stmts.get(0).getType());
+ }
+
+ @Test
+ public void shouldParseAlterTableAddREF() {
+ System.out.println("TEST: shouldParseAlterTableAddREF()");
+ String content = "ALTER TABLE staff ADD (REF(dept) WITH ROWID);";
+ parser.setDoUseTerminator(true);
+ List<Statement> stmts = parser.parse(content);
+ assertEquals("ALTER TABLE", stmts.get(0).getType());
+ }
+
+ @Test
+ public void shouldParseAlterTableADDWithNESTED_TABLE() {
+ // This is a one-off case where there is a custom datatype (i.e. skill_table_type)
+ System.out.println("TEST: shouldParseAlterTableADDWithNESTED_TABLE()");
+ String content = "ALTER TABLE employees ADD (skills skill_table_type) NESTED TABLE skills STORE AS nested_skill_table;";
+ parser.setDoUseTerminator(true);
+ List<Statement> stmts = parser.parse(content);
+ assertEquals("ALTER TABLE", stmts.get(0).getType());
+ }
+
+ @Test
+ public void shouldParseAlterIndexRename() {
+ System.out.println("TEST: shouldParseAlterIndexRename()");
+ String content = "ALTER INDEX upper_ix RENAME TO upper_name_ix;";
+ parser.setDoUseTerminator(true);
+ List<Statement> stmts = parser.parse(content);
+ assertEquals("ALTER INDEX", stmts.get(0).getType());
+ }
+
+ @Test
+ public void shouldParseAlterIndexMODIFY() {
+ System.out.println("TEST: shouldParseAlterIndexMODIFY()");
+ String content = "ALTER INDEX cost_ix MODIFY PARTITION p3 STORAGE(MAXEXTENTS 30) LOGGING;";
+ parser.setDoUseTerminator(true);
+ List<Statement> stmts = parser.parse(content);
+ assertEquals("ALTER INDEX", stmts.get(0).getType());
+ }
+
+ @Test
+ public void shouldParseAlterIndexDROP() {
+ System.out.println("TEST: shouldParseAlterIndexDROP()");
+ String content = "ALTER INDEX cost_ix DROP PARTITION p1;";
+ parser.setDoUseTerminator(true);
+ List<Statement> stmts = parser.parse(content);
+ assertEquals("ALTER INDEX", stmts.get(0).getType());
+ }
+
+ @Test
+ public void shouldParseAlterIndexTypeADD() {
+ System.out.println("TEST: shouldParseAlterIndexTypeADD()");
+ String content = "ALTER INDEXTYPE position_indextype ADD lob_contains(CLOB, CLOB);";
+ parser.setDoUseTerminator(true);
+ List<Statement> stmts = parser.parse(content);
+ assertEquals("ALTER INDEXTYPE", stmts.get(0).getType());
+ }
+
+ @Test
+ public void shouldParseTEMP_TEST() {
+ System.out.println("TEST: shouldParseTEMP_TEST()");
+ String content = "COMMENT ON COLUMN employees.job_id IS 'abbreviated job title';";
+ parser.setDoUseTerminator(true);
+ List<Statement> stmts = parser.parse(content);
+
+ }
+
+ @Test
+ public void shouldParseOracleStatements() {
+ System.out.println("TEST: shouldParseOracleStatements()");
+ String content = getFileContent(DDL_FILE_PATH + "oracle_test_statements.ddl");
+ parser.setDoUseTerminator(true);
+ List<Statement> stmts = parser.parse(content);
+ assertEquals(198, stmts.size());
+ System.out.println(" END PARSING. # Statements = " + stmts.size());
+
+ }
+
+// @Test
+// public void shouldParseGFM_PhysicalDDL() {
+// String content = getFileContent(DDL_FILE_PATH + "GFM_Physical.ddl");
+// parser.setDoUseTerminator(true);
+// List<Statement> stmts = parser.parse(content);
+//
+// System.out.println(" END PARSING. # Statements = " + stmts.size());
+//
+// }
+
+}
\ No newline at end of file
Property changes on: branches/ddl_sequencer/extensions/dna-sequencer-ddl/src/test/java/org/jboss/dna/sequencer/ddl/dialect/OracleDdlParserTest.java
___________________________________________________________________
Name: svn:mime-type
+ text/plain
Added: branches/ddl_sequencer/extensions/dna-sequencer-ddl/src/test/resources/sql2bnf.aug92.txt
===================================================================
--- branches/ddl_sequencer/extensions/dna-sequencer-ddl/src/test/resources/sql2bnf.aug92.txt (rev 0)
+++ branches/ddl_sequencer/extensions/dna-sequencer-ddl/src/test/resources/sql2bnf.aug92.txt 2009-10-02 16:13:40 UTC (rev 1280)
@@ -0,0 +1,2594 @@
+This file contains a depth-first tree traversal of the BNF
+for the language done at about 27-AUG-1992 11:03:41.64.
+The specific version of the BNF included here is: ANSI-only, SQL2-only.
+
+
+<SQL terminal character> ::=
+ <SQL language character>
+ | <SQL embedded language character>
+
+<SQL language character> ::=
+ <simple Latin letter>
+ | <digit>
+ | <SQL special character>
+
+<simple Latin letter> ::=
+ <simple Latin upper case letter>
+ | <simple Latin lower case letter>
+
+<simple Latin upper case letter> ::=
+ A | B | C | D | E | F | G | H | I | J | K | L | M | N | O
+ | P | Q | R | S | T | U | V | W | X | Y | Z
+
+<simple Latin lower case letter> ::=
+ a | b | c | d | e | f | g | h | i | j | k | l | m | n | o
+ | p | q | r | s | t | u | v | w | x | y | z
+
+<digit> ::=
+ 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9
+
+<SQL special character> ::=
+ <space>
+ | <double quote>
+ | <percent>
+ | <ampersand>
+ | <quote>
+ | <left paren>
+ | <right paren>
+ | <asterisk>
+ | <plus sign>
+ | <comma>
+ | <minus sign>
+ | <period>
+ | <solidus>
+ | <colon>
+ | <semicolon>
+ | <less than operator>
+ | <equals operator>
+ | <greater than operator>
+ | <question mark>
+ | <underscore>
+ | <vertical bar>
+
+<space> ::= !! <EMPHASIS>(space character in character set in use)
+
+<double quote> ::= "
+
+<percent> ::= %
+
+<ampersand> ::= &
+
+<quote> ::= '
+
+<left paren> ::= (
+
+<right paren> ::= )
+
+<asterisk> ::= *
+
+<plus sign> ::= +
+
+<comma> ::= ,
+
+<minus sign> ::= -
+
+<period> ::= .
+
+<solidus> ::= /
+
+<colon> ::= :
+
+<semicolon> ::= ;
+
+<less than operator> ::= <
+
+<equals operator> ::= =
+
+<greater than operator> ::= >
+
+<question mark> ::= ?
+
+<underscore> ::= _
+
+<vertical bar> ::= |
+
+<SQL embedded language character> ::=
+ <left bracket>
+ | <right bracket>
+
+<left bracket> ::= [
+
+<right bracket> ::= ]
+
+<token> ::=
+ <nondelimiter token>
+ | <delimiter token>
+
+<nondelimiter token> ::=
+ <regular identifier>
+ | <key word>
+ | <unsigned numeric literal>
+ | <national character string literal>
+ | <bit string literal>
+ | <hex string literal>
+
+<regular identifier> ::= <identifier body>
+
+<identifier body> ::=
+ <identifier start> [ { <underscore> | <identifier part> }... ]
+
+<identifier start> ::= <EMPHASIS>(!! See the Syntax Rules)
+
+<identifier part> ::=
+ <identifier start>
+ | <digit>
+
+<key word> ::=
+ <reserved word>
+ | <non-reserved word>
+
+<reserved word> ::=
+ ABSOLUTE | ACTION | ADD | ALL
+ | ALLOCATE | ALTER | AND
+ | ANY | ARE
+ | AS | ASC
+ | ASSERTION | AT
+ | AUTHORIZATION | AVG
+ | BEGIN | BETWEEN | BIT | BIT_LENGTH
+ | BOTH | BY
+ | CASCADE | CASCADED | CASE | CAST
+ | CATALOG
+ | CHAR | CHARACTER | CHAR_LENGTH
+ | CHARACTER_LENGTH | CHECK | CLOSE | COALESCE
+ | COLLATE | COLLATION
+ | COLUMN | COMMIT
+ | CONNECT
+ | CONNECTION | CONSTRAINT
+ | CONSTRAINTS | CONTINUE
+ | CONVERT | CORRESPONDING | COUNT | CREATE | CROSS
+ | CURRENT
+ | CURRENT_DATE | CURRENT_TIME
+ | CURRENT_TIMESTAMP | CURRENT_USER | CURSOR
+ | DATE | DAY | DEALLOCATE | DEC
+ | DECIMAL | DECLARE | DEFAULT | DEFERRABLE
+ | DEFERRED | DELETE | DESC | DESCRIBE | DESCRIPTOR
+ | DIAGNOSTICS
+ | DISCONNECT | DISTINCT | DOMAIN | DOUBLE | DROP
+ | ELSE | END | END-EXEC | ESCAPE
+ | EXCEPT | EXCEPTION
+ | EXEC | EXECUTE | EXISTS
+ | EXTERNAL | EXTRACT
+ | FALSE | FETCH | FIRST | FLOAT | FOR
+ | FOREIGN | FOUND | FROM | FULL
+ | GET | GLOBAL | GO | GOTO
+ | GRANT | GROUP
+ | HAVING | HOUR
+ | IDENTITY | IMMEDIATE | IN | INDICATOR
+ | INITIALLY | INNER | INPUT
+ | INSENSITIVE | INSERT | INT | INTEGER | INTERSECT
+ | INTERVAL | INTO | IS
+ | ISOLATION
+ | JOIN
+ | KEY
+ | LANGUAGE | LAST | LEADING | LEFT
+ | LEVEL | LIKE | LOCAL | LOWER
+ | MATCH | MAX | MIN | MINUTE | MODULE
+ | MONTH
+ | NAMES | NATIONAL | NATURAL | NCHAR | NEXT | NO
+ | NOT | NULL
+ | NULLIF | NUMERIC
+ | OCTET_LENGTH | OF
+ | ON | ONLY | OPEN | OPTION | OR
+ | ORDER | OUTER
+ | OUTPUT | OVERLAPS
+ | PAD | PARTIAL | POSITION | PRECISION | PREPARE
+ | PRESERVE | PRIMARY
+ | PRIOR | PRIVILEGES | PROCEDURE | PUBLIC
+ | READ | REAL | REFERENCES | RELATIVE | RESTRICT
+ | REVOKE | RIGHT
+ | ROLLBACK | ROWS
+ | SCHEMA | SCROLL | SECOND | SECTION
+ | SELECT
+ | SESSION | SESSION_USER | SET
+ | SIZE | SMALLINT | SOME | SPACE | SQL | SQLCODE
+ | SQLERROR | SQLSTATE
+ | SUBSTRING | SUM | SYSTEM_USER
+ | TABLE | TEMPORARY
+ | THEN | TIME | TIMESTAMP
+ | TIMEZONE_HOUR | TIMEZONE_MINUTE
+ | TO | TRAILING | TRANSACTION
+ | TRANSLATE | TRANSLATION | TRIM | TRUE
+ | UNION | UNIQUE | UNKNOWN | UPDATE | UPPER | USAGE
+ | USER | USING
+ | VALUE | VALUES | VARCHAR | VARYING | VIEW
+ | WHEN | WHENEVER | WHERE | WITH | WORK | WRITE
+ | YEAR
+ | ZONE
+
+<non-reserved word> ::=
+
+ ADA
+ | C | CATALOG_NAME
+ | CHARACTER_SET_CATALOG | CHARACTER_SET_NAME
+ | CHARACTER_SET_SCHEMA | CLASS_ORIGIN | COBOL | COLLATION_CATALOG
+ | COLLATION_NAME | COLLATION_SCHEMA | COLUMN_NAME | COMMAND_FUNCTION
+ | COMMITTED
+ | CONDITION_NUMBER | CONNECTION_NAME | CONSTRAINT_CATALOG | CONSTRAINT_NAME
+ | CONSTRAINT_SCHEMA | CURSOR_NAME
+ | DATA | DATETIME_INTERVAL_CODE
+ | DATETIME_INTERVAL_PRECISION | DYNAMIC_FUNCTION
+ | FORTRAN
+ | LENGTH
+ | MESSAGE_LENGTH | MESSAGE_OCTET_LENGTH | MESSAGE_TEXT | MORE | MUMPS
+ | NAME | NULLABLE | NUMBER
+ | PASCAL | PLI
+ | REPEATABLE | RETURNED_LENGTH | RETURNED_OCTET_LENGTH | RETURNED_SQLSTATE
+ | ROW_COUNT
+ | SCALE | SCHEMA_NAME | SERIALIZABLE | SERVER_NAME | SUBCLASS_ORIGIN
+ | TABLE_NAME | TYPE
+ | UNCOMMITTED | UNNAMED
+
+<unsigned numeric literal> ::=
+ <exact numeric literal>
+ | <approximate numeric literal>
+
+<exact numeric literal> ::=
+ <unsigned integer> [ <period> [ <unsigned integer> ] ]
+ | <period> <unsigned integer>
+
+<unsigned integer> ::= <digit>...
+
+<approximate numeric literal> ::= <mantissa> E <exponent>
+
+<mantissa> ::= <exact numeric literal>
+
+<exponent> ::= <signed integer>
+
+<signed integer> ::= [ <sign> ] <unsigned integer>
+
+<sign> ::= <plus sign> | <minus sign>
+
+<national character string literal> ::=
+ N <quote> [ <character representation>... ] <quote>
+ [ { <separator>... <quote> [ <character representation>... ] <quote> }... ]
+
+<character representation> ::=
+ <nonquote character>
+ | <quote symbol>
+
+<nonquote character> ::= !! <EMPHASIS>(See the Syntax Rules.)
+
+<quote symbol> ::= <quote><quote>
+
+<separator> ::= { <comment> | <space> | <newline> }...
+
+<comment> ::=
+ <comment introducer> [ <comment character>... ] <newline>
+
+<comment introducer> ::= <minus sign><minus sign>[<minus sign>...]
+
+<comment character> ::=
+ <nonquote character>
+ | <quote>
+
+<newline> ::= !! <EMPHASIS>(implementation-defined end-of-line indicator)
+
+<bit string literal> ::=
+ B <quote> [ <bit>... ] <quote>
+ [ { <separator>... <quote> [ <bit>... ] <quote> }... ]
+
+<bit> ::= 0 | 1
+
+<hex string literal> ::=
+ X <quote> [ <hexit>... ] <quote>
+ [ { <separator>... <quote> [ <hexit>... ] <quote> }... ]
+
+<hexit> ::= <digit> | A | B | C | D | E | F | a | b | c | d | e | f
+
+<delimiter token> ::=
+ <character string literal>
+ | <date string>
+ | <time string>
+ | <timestamp string>
+ | <interval string>
+ | <delimited identifier>
+ | <SQL special character>
+ | <not equals operator>
+ | <greater than or equals operator>
+ | <less than or equals operator>
+ | <concatenation operator>
+ | <double period>
+ | <left bracket>
+ | <right bracket>
+
+<character string literal> ::=
+ [ <introducer><character set specification> ]
+ <quote> [ <character representation>... ] <quote>
+ [ { <separator>... <quote> [ <character representation>... ] <quote> }... ]
+
+<introducer> ::= <underscore>
+
+<character set specification> ::=
+ <standard character repertoire name>
+ | <implementation-defined character repertoire name>
+ | <user-defined character repertoire name>
+ | <standard universal character form-of-use name>
+ | <implementation-defined universal character form-of-use name>
+
+<standard character repertoire name> ::= <character set name>
+
+<character set name> ::= [ <schema name> <period> ]
+ <SQL language identifier>
+
+<schema name> ::=
+ [ <catalog name> <period> ] <unqualified schema name>
+
+<catalog name> ::= <identifier>
+
+<identifier> ::=
+ [ <introducer><character set specification> ] <actual identifier>
+
+<actual identifier> ::=
+ <regular identifier>
+ | <delimited identifier>
+
+<delimited identifier> ::=
+ <double quote> <delimited identifier body> <double quote>
+
+<delimited identifier body> ::= <delimited identifier part>...
+
+<delimited identifier part> ::=
+ <nondoublequote character>
+ | <doublequote symbol>
+
+<nondoublequote character> ::= <EMPHASIS>(!! See the Syntax Rules)
+
+<doublequote symbol> ::= <double quote><double quote>
+
+<unqualified schema name> ::= <identifier>
+
+<SQL language identifier> ::=
+ <SQL language identifier start>
+ [ { <underscore> | <SQL language identifier part> }... ]
+
+<SQL language identifier start> ::= <simple Latin letter>
+
+<SQL language identifier part> ::=
+ <simple Latin letter>
+ | <digit>
+
+<implementation-defined character repertoire name> ::=
+ <character set name>
+
+<user-defined character repertoire name> ::= <character set name>
+
+<standard universal character form-of-use name> ::=
+ <character set name>
+
+<implementation-defined universal character form-of-use name> ::=
+ <character set name>
+
+<date string> ::=
+ <quote> <date value> <quote>
+
+<date value> ::=
+ <years value> <minus sign> <months value>
+ <minus sign> <days value>
+
+<years value> ::= <datetime value>
+
+<datetime value> ::= <unsigned integer>
+
+<months value> ::= <datetime value>
+
+<days value> ::= <datetime value>
+
+<time string> ::=
+ <quote> <time value> [ <time zone interval> ] <quote>
+
+<time value> ::=
+ <hours value> <colon> <minutes value> <colon> <seconds value>
+
+<hours value> ::= <datetime value>
+
+<minutes value> ::= <datetime value>
+
+<seconds value> ::=
+ <seconds integer value> [ <period> [ <seconds fraction> ] ]
+
+<seconds integer value> ::= <unsigned integer>
+
+<seconds fraction> ::= <unsigned integer>
+
+<time zone interval> ::=
+ <sign> <hours value> <colon> <minutes value>
+
+<timestamp string> ::=
+ <quote> <date value> <space> <time value>
+ [ <time zone interval> ] <quote>
+
+<interval string> ::=
+ <quote> { <year-month literal> | <day-time literal> } <quote>
+
+<year-month literal> ::=
+ <years value>
+ | [ <years value> <minus sign> ] <months value>
+
+<day-time literal> ::=
+ <day-time interval>
+ | <time interval>
+
+<day-time interval> ::=
+ <days value>
+ [ <space> <hours value> [ <colon> <minutes value>
+ [ <colon> <seconds value> ] ] ]
+
+<time interval> ::=
+ <hours value> [ <colon> <minutes value> [ <colon> <seconds value> ] ]
+ | <minutes value> [ <colon> <seconds value> ]
+ | <seconds value>
+
+<not equals operator> ::= <>
+
+<greater than or equals operator> ::= >=
+
+<less than or equals operator> ::= <=
+
+<concatenation operator> ::= ||
+
+<double period> ::= ..
+
+<module> ::=
+ <module name clause>
+ <language clause>
+ <module authorization clause>
+ [ <temporary table declaration>... ]
+ <module contents>...
+
+<module name clause> ::=
+ MODULE [ <module name> ]
+ [ <module character set specification> ]
+
+<module name> ::= <identifier>
+
+<module character set specification> ::=
+ NAMES ARE <character set specification>
+
+<language clause> ::=
+ LANGUAGE <language name>
+
+<language name> ::=
+ ADA | C | COBOL | FORTRAN | MUMPS | PASCAL | PLI
+
+<module authorization clause> ::=
+ SCHEMA <schema name>
+ | AUTHORIZATION <module authorization identifier>
+ | SCHEMA <schema name>
+ AUTHORIZATION <module authorization identifier>
+
+<module authorization identifier> ::=
+ <authorization identifier>
+
+<authorization identifier> ::= <identifier>
+
+<temporary table declaration> ::=
+ DECLARE LOCAL TEMPORARY TABLE
+ <qualified local table name>
+ <table element list>
+ [ ON COMMIT { PRESERVE | DELETE } ROWS ]
+
+<qualified local table name> ::=
+ MODULE <period> <local table name>
+
+<local table name> ::= <qualified identifier>
+
+<qualified identifier> ::= <identifier>
+
+<table element list> ::=
+ <left paren> <table element> [ { <comma> <table element> }... ] <right paren>
+
+<table element> ::=
+ <column definition>
+ | <table constraint definition>
+
+<column definition> ::=
+ <column name> { <data type> | <domain name> }
+ [ <default clause> ]
+ [ <column constraint definition>... ]
+ [ <collate clause> ]
+
+<column name> ::= <identifier>
+
+<data type> ::=
+ <character string type>
+ [ CHARACTER SET <character set specification> ]
+ | <national character string type>
+ | <bit string type>
+ | <numeric type>
+ | <datetime type>
+ | <interval type>
+
+<character string type> ::=
+ CHARACTER [ <left paren> <length> <right paren> ]
+ | CHAR [ <left paren> <length> <right paren> ]
+ | CHARACTER VARYING <left paren> <length> <right paren>
+ | CHAR VARYING <left paren> <length> <right paren>
+ | VARCHAR <left paren> <length> <right paren>
+
+<length> ::= <unsigned integer>
+
+<national character string type> ::=
+ NATIONAL CHARACTER [ <left paren> <length> <right paren> ]
+ | NATIONAL CHAR [ <left paren> <length> <right paren> ]
+ | NCHAR [ <left paren> <length> <right paren> ]
+ | NATIONAL CHARACTER VARYING <left paren> <length> <right paren>
+ | NATIONAL CHAR VARYING <left paren> <length> <right paren>
+ | NCHAR VARYING <left paren> <length> <right paren>
+
+<bit string type> ::=
+ BIT [ <left paren> <length> <right paren> ]
+ | BIT VARYING <left paren> <length> <right paren>
+
+<numeric type> ::=
+ <exact numeric type>
+ | <approximate numeric type>
+
+<exact numeric type> ::=
+ NUMERIC [ <left paren> <precision> [ <comma> <scale> ] <right paren> ]
+ | DECIMAL [ <left paren> <precision> [ <comma> <scale> ] <right paren> ]
+ | DEC [ <left paren> <precision> [ <comma> <scale> ] <right paren> ]
+ | INTEGER
+ | INT
+ | SMALLINT
+
+<precision> ::= <unsigned integer>
+
+<scale> ::= <unsigned integer>
+
+<approximate numeric type> ::=
+ FLOAT [ <left paren> <precision> <right paren> ]
+ | REAL
+ | DOUBLE PRECISION
+
+<datetime type> ::=
+ DATE
+ | TIME [ <left paren> <time precision> <right paren> ]
+ [ WITH TIME ZONE ]
+ | TIMESTAMP [ <left paren> <timestamp precision> <right paren> ]
+ [ WITH TIME ZONE ]
+
+<time precision> ::= <time fractional seconds precision>
+
+<time fractional seconds precision> ::= <unsigned integer>
+
+<timestamp precision> ::= <time fractional seconds precision>
+
+<interval type> ::= INTERVAL <interval qualifier>
+
+<interval qualifier> ::=
+ <start field> TO <end field>
+ | <single datetime field>
+
+<start field> ::=
+ <non-second datetime field>
+ [ <left paren> <interval leading field precision> <right paren> ]
+
+<non-second datetime field> ::= YEAR | MONTH | DAY | HOUR
+ | MINUTE
+
+<interval leading field precision> ::= <unsigned integer>
+
+<end field> ::=
+ <non-second datetime field>
+ | SECOND [ <left paren> <interval fractional seconds precision> <right paren> ]
+
+<interval fractional seconds precision> ::= <unsigned integer>
+
+<single datetime field> ::=
+ <non-second datetime field>
+ [ <left paren> <interval leading field precision> <right paren> ]
+ | SECOND [ <left paren> <interval leading field precision>
+ [ <comma> <interval fractional seconds precision> ] <right paren> ]
+
+<domain name> ::= <qualified name>
+
+<qualified name> ::=
+ [ <schema name> <period> ] <qualified identifier>
+
+<default clause> ::=
+ DEFAULT <default option>
+
+<default option> ::=
+ <literal>
+ | <datetime value function>
+ | USER
+ | CURRENT_USER
+ | SESSION_USER
+ | SYSTEM_USER
+ | NULL
+
+<literal> ::=
+ <signed numeric literal>
+ | <general literal>
+
+<signed numeric literal> ::=
+ [ <sign> ] <unsigned numeric literal>
+
+<general literal> ::=
+ <character string literal>
+ | <national character string literal>
+ | <bit string literal>
+ | <hex string literal>
+ | <datetime literal>
+ | <interval literal>
+
+<datetime literal> ::=
+ <date literal>
+ | <time literal>
+ | <timestamp literal>
+
+<date literal> ::=
+ DATE <date string>
+
+<time literal> ::=
+ TIME <time string>
+
+<timestamp literal> ::=
+ TIMESTAMP <timestamp string>
+
+<interval literal> ::=
+ INTERVAL [ <sign> ] <interval string> <interval qualifier>
+
+<datetime value function> ::=
+ <current date value function>
+ | <current time value function>
+ | <current timestamp value function>
+
+<current date value function> ::= CURRENT_DATE
+
+<current time value function> ::=
+ CURRENT_TIME [ <left paren> <time precision> <right paren> ]
+
+<current timestamp value function> ::=
+ CURRENT_TIMESTAMP [ <left paren> <timestamp precision> <right paren> ]
+
+<column constraint definition> ::=
+ [ <constraint name definition> ]
+ <column constraint>
+ [ <constraint attributes> ]
+
+<constraint name definition> ::= CONSTRAINT <constraint name>
+
+<constraint name> ::= <qualified name>
+
+<column constraint> ::=
+ NOT NULL
+ | <unique specification>
+ | <references specification>
+ | <check constraint definition>
+
+<unique specification> ::=
+ UNIQUE | PRIMARY KEY
+
+<references specification> ::=
+ REFERENCES <referenced table and columns>
+ [ MATCH <match type> ]
+ [ <referential triggered action> ]
+
+<referenced table and columns> ::=
+ <table name> [ <left paren> <reference column list> <right paren> ]
+
+<table name> ::=
+ <qualified name>
+ | <qualified local table name>
+
+<reference column list> ::= <column name list>
+
+<column name list> ::=
+ <column name> [ { <comma> <column name> }... ]
+
+<match type> ::=
+ FULL
+ | PARTIAL
+
+<referential triggered action> ::=
+ <update rule> [ <delete rule> ]
+ | <delete rule> [ <update rule> ]
+
+<update rule> ::= ON UPDATE <referential action>
+
+<referential action> ::=
+ CASCADE
+ | SET NULL
+ | SET DEFAULT
+ | NO ACTION
+
+<delete rule> ::= ON DELETE <referential action>
+
+<check constraint definition> ::=
+ CHECK
+ <left paren> <search condition> <right paren>
+
+<search condition> ::=
+ <boolean term>
+ | <search condition> OR <boolean term>
+
+<boolean term> ::=
+ <boolean factor>
+ | <boolean term> AND <boolean factor>
+
+<boolean factor> ::=
+ [ NOT ] <boolean test>
+
+<boolean test> ::=
+ <boolean primary> [ IS [ NOT ]
+ <truth value> ]
+
+<boolean primary> ::=
+ <predicate>
+ | <left paren> <search condition> <right paren>
+
+<predicate> ::=
+ <comparison predicate>
+ | <between predicate>
+ | <in predicate>
+ | <like predicate>
+ | <null predicate>
+ | <quantified comparison predicate>
+ | <exists predicate>
+ | <unique predicate>
+ | <match predicate>
+ | <overlaps predicate>
+
+<comparison predicate> ::=
+ <row value constructor> <comp op>
+ <row value constructor>
+
+<row value constructor> ::=
+ <row value constructor element>
+ | <left paren> <row value constructor list> <right paren>
+ | <row subquery>
+
+<row value constructor element> ::=
+ <value expression>
+ | <null specification>
+ | <default specification>
+
+<value expression> ::=
+ <numeric value expression>
+ | <string value expression>
+ | <datetime value expression>
+ | <interval value expression>
+
+<numeric value expression> ::=
+ <term>
+ | <numeric value expression> <plus sign> <term>
+ | <numeric value expression> <minus sign> <term>
+
+<term> ::=
+ <factor>
+ | <term> <asterisk> <factor>
+ | <term> <solidus> <factor>
+
+<factor> ::=
+ [ <sign> ] <numeric primary>
+
+<numeric primary> ::=
+ <value expression primary>
+ | <numeric value function>
+
+<value expression primary> ::=
+ <unsigned value specification>
+ | <column reference>
+ | <set function specification>
+ | <scalar subquery>
+ | <case expression>
+ | <left paren> <value expression> <right paren>
+ | <cast specification>
+
+<unsigned value specification> ::=
+ <unsigned literal>
+ | <general value specification>
+
+<unsigned literal> ::=
+ <unsigned numeric literal>
+ | <general literal>
+
+<general value specification> ::=
+ <parameter specification>
+ | <dynamic parameter specification>
+ | <variable specification>
+ | USER
+ | CURRENT_USER
+ | SESSION_USER
+ | SYSTEM_USER
+ | VALUE
+
+<parameter specification> ::=
+ <parameter name> [ <indicator parameter> ]
+
+<parameter name> ::= <colon> <identifier>
+
+<indicator parameter> ::=
+ [ INDICATOR ] <parameter name>
+
+<dynamic parameter specification> ::= <question mark>
+
+<variable specification> ::=
+ <embedded variable name> [ <indicator variable> ]
+
+<embedded variable name> ::=
+ <colon><host identifier>
+
+<host identifier> ::=
+ <Ada host identifier>
+ | <C host identifier>
+ | <COBOL host identifier>
+ | <Fortran host identifier>
+ | <MUMPS host identifier>
+ | <Pascal host identifier>
+ | <PL/I host identifier>
+
+<Ada host identifier> ::= !! <EMPHASIS>(See the Syntax Rules.)
+
+<C host identifier> ::=
+ !! <EMPHASIS>(See the Syntax Rules.)
+
+<COBOL host identifier> ::= !! <EMPHASIS>(See the Syntax Rules.)
+
+<Fortran host identifier> ::= !! <EMPHASIS>(See the Syntax Rules.)
+
+<MUMPS host identifier> ::= !! <EMPHASIS>(See the Syntax Rules.)
+
+<Pascal host identifier> ::= !! <EMPHASIS>(See the Syntax Rules.)
+
+<PL/I host identifier> ::= !! <EMPHASIS>(See the Syntax Rules.)
+
+<indicator variable> ::=
+ [ INDICATOR ] <embedded variable name>
+
+<column reference> ::= [ <qualifier> <period> ] <column name>
+
+<qualifier> ::=
+ <table name>
+ | <correlation name>
+
+<correlation name> ::= <identifier>
+
+<set function specification> ::=
+ COUNT <left paren> <asterisk> <right paren>
+ | <general set function>
+
+<general set function> ::=
+ <set function type>
+ <left paren> [ <set quantifier> ] <value expression> <right paren>
+
+<set function type> ::=
+ AVG | MAX | MIN | SUM | COUNT
+
+<set quantifier> ::= DISTINCT | ALL
+
+<scalar subquery> ::= <subquery>
+
+<subquery> ::= <left paren> <query expression> <right paren>
+
+<query expression> ::=
+ <non-join query expression>
+ | <joined table>
+
+<non-join query expression> ::=
+ <non-join query term>
+ | <query expression> UNION [ ALL ]
+ [ <corresponding spec> ] <query term>
+ | <query expression> EXCEPT [ ALL ]
+ [ <corresponding spec> ] <query term>
+
+<non-join query term> ::=
+ <non-join query primary>
+ | <query term> INTERSECT [ ALL ]
+ [ <corresponding spec> ] <query primary>
+
+<non-join query primary> ::=
+ <simple table>
+ | <left paren> <non-join query expression> <right paren>
+
+<simple table> ::=
+ <query specification>
+ | <table value constructor>
+ | <explicit table>
+
+<query specification> ::=
+ SELECT [ <set quantifier> ] <select list> <table expression>
+
+<select list> ::=
+ <asterisk>
+ | <select sublist> [ { <comma> <select sublist> }... ]
+
+<select sublist> ::=
+ <derived column>
+ | <qualifier> <period> <asterisk>
+
+<derived column> ::= <value expression> [ <as clause> ]
+
+<as clause> ::= [ AS ] <column name>
+
+<table expression> ::=
+ <from clause>
+ [ <where clause> ]
+ [ <group by clause> ]
+ [ <having clause> ]
+
+<from clause> ::= FROM <table reference>
+ [ { <comma> <table reference> }... ]
+
+<table reference> ::=
+ <table name> [ [ AS ] <correlation name>
+ [ <left paren> <derived column list> <right paren> ] ]
+ | <derived table> [ AS ] <correlation name>
+ [ <left paren> <derived column list> <right paren> ]
+ | <joined table>
+
+<derived column list> ::= <column name list>
+
+<derived table> ::= <table subquery>
+
+<table subquery> ::= <subquery>
+
+<joined table> ::=
+ <cross join>
+ | <qualified join>
+ | <left paren> <joined table> <right paren>
+
+<cross join> ::=
+ <table reference> CROSS JOIN <table reference>
+
+<qualified join> ::=
+ <table reference> [ NATURAL ] [ <join type> ] JOIN
+ <table reference> [ <join specification> ]
+
+<join type> ::=
+ INNER
+ | <outer join type> [ OUTER ]
+ | UNION
+
+<outer join type> ::=
+ LEFT
+ | RIGHT
+ | FULL
+
+<join specification> ::=
+ <join condition>
+ | <named columns join>
+
+<join condition> ::= ON <search condition>
+
+<named columns join> ::=
+ USING <left paren> <join column list> <right paren>
+
+<join column list> ::= <column name list>
+
+<where clause> ::= WHERE <search condition>
+
+<group by clause> ::=
+ GROUP BY <grouping column reference list>
+
+<grouping column reference list> ::=
+ <grouping column reference>
+ [ { <comma> <grouping column reference> }... ]
+
+<grouping column reference> ::=
+ <column reference> [ <collate clause> ]
+
+<collate clause> ::= COLLATE <collation name>
+
+<collation name> ::= <qualified name>
+
+<having clause> ::= HAVING <search condition>
+
+<table value constructor> ::=
+ VALUES <table value constructor list>
+
+<table value constructor list> ::=
+ <row value constructor> [ { <comma> <row value constructor> }... ]
+
+<explicit table> ::= TABLE <table name>
+
+<query term> ::=
+ <non-join query term>
+ | <joined table>
+
+<corresponding spec> ::=
+ CORRESPONDING [ BY <left paren> <corresponding column list> <right paren> ]
+
+<corresponding column list> ::= <column name list>
+
+<query primary> ::=
+ <non-join query primary>
+ | <joined table>
+
+<case expression> ::=
+ <case abbreviation>
+ | <case specification>
+
+<case abbreviation> ::=
+ NULLIF <left paren> <value expression> <comma>
+ <value expression> <right paren>
+ | COALESCE <left paren> <value expression>
+ { <comma> <value expression> }... <right paren>
+
+<case specification> ::=
+ <simple case>
+ | <searched case>
+
+<simple case> ::=
+ CASE <case operand>
+ <simple when clause>...
+ [ <else clause> ]
+ END
+
+<case operand> ::= <value expression>
+
+<simple when clause> ::= WHEN <when operand> THEN <result>
+
+<when operand> ::= <value expression>
+
+<result> ::= <result expression> | NULL
+
+<result expression> ::= <value expression>
+
+<else clause> ::= ELSE <result>
+
+<searched case> ::=
+ CASE
+ <searched when clause>...
+ [ <else clause> ]
+ END
+
+<searched when clause> ::= WHEN <search condition> THEN <result>
+
+<cast specification> ::=
+ CAST <left paren> <cast operand> AS
+ <cast target> <right paren>
+
+<cast operand> ::=
+ <value expression>
+ | NULL
+
+<cast target> ::=
+ <domain name>
+ | <data type>
+
+<numeric value function> ::=
+ <position expression>
+ | <extract expression>
+ | <length expression>
+
+<position expression> ::=
+ POSITION <left paren> <character value expression>
+ IN <character value expression> <right paren>
+
+<character value expression> ::=
+ <concatenation>
+ | <character factor>
+
+<concatenation> ::=
+ <character value expression> <concatenation operator>
+ <character factor>
+
+<character factor> ::=
+ <character primary> [ <collate clause> ]
+
+<character primary> ::=
+ <value expression primary>
+ | <string value function>
+
+<string value function> ::=
+ <character value function>
+ | <bit value function>
+
+<character value function> ::=
+ <character substring function>
+ | <fold>
+ | <form-of-use conversion>
+ | <character translation>
+ | <trim function>
+
+<character substring function> ::=
+ SUBSTRING <left paren> <character value expression> FROM <start position>
+ [ FOR <string length> ] <right paren>
+
+<start position> ::= <numeric value expression>
+
+<string length> ::= <numeric value expression>
+
+<fold> ::= { UPPER | LOWER }
+ <left paren> <character value expression> <right paren>
+
+<form-of-use conversion> ::=
+ CONVERT <left paren> <character value expression>
+ USING <form-of-use conversion name> <right paren>
+
+<form-of-use conversion name> ::= <qualified name>
+
+<character translation> ::=
+ TRANSLATE <left paren> <character value expression>
+ USING <translation name> <right paren>
+
+<translation name> ::= <qualified name>
+
+<trim function> ::=
+ TRIM <left paren> <trim operands> <right paren>
+
+<trim operands> ::=
+ [ [ <trim specification> ] [ <trim character> ] FROM ] <trim source>
+
+<trim specification> ::=
+ LEADING
+ | TRAILING
+ | BOTH
+
+<trim character> ::= <character value expression>
+
+<trim source> ::= <character value expression>
+
+<bit value function> ::=
+ <bit substring function>
+
+<bit substring function> ::=
+ SUBSTRING <left paren> <bit value expression> FROM <start position>
+ [ FOR <string length> ] <right paren>
+
+<bit value expression> ::=
+ <bit concatenation>
+ | <bit factor>
+
+<bit concatenation> ::=
+ <bit value expression> <concatenation operator> <bit factor>
+
+<bit factor> ::= <bit primary>
+
+<bit primary> ::=
+ <value expression primary>
+ | <string value function>
+
+<extract expression> ::=
+ EXTRACT <left paren> <extract field>
+ FROM <extract source> <right paren>
+
+<extract field> ::=
+ <datetime field>
+ | <time zone field>
+
+<datetime field> ::=
+ <non-second datetime field>
+ | SECOND
+
+<time zone field> ::=
+ TIMEZONE_HOUR
+ | TIMEZONE_MINUTE
+
+<extract source> ::=
+ <datetime value expression>
+ | <interval value expression>
+
+<datetime value expression> ::=
+ <datetime term>
+ | <interval value expression> <plus sign> <datetime term>
+ | <datetime value expression> <plus sign> <interval term>
+ | <datetime value expression> <minus sign> <interval term>
+
+<interval term> ::=
+ <interval factor>
+ | <interval term 2> <asterisk> <factor>
+ | <interval term 2> <solidus> <factor>
+ | <term> <asterisk> <interval factor>
+
+<interval factor> ::=
+ [ <sign> ] <interval primary>
+
+<interval primary> ::=
+ <value expression primary> [ <interval qualifier> ]
+
+<interval term 2> ::= <interval term>
+
+<interval value expression> ::=
+ <interval term>
+ | <interval value expression 1> <plus sign> <interval term 1>
+ | <interval value expression 1> <minus sign> <interval term 1>
+ | <left paren> <datetime value expression> <minus sign>
+ <datetime term> <right paren> <interval qualifier>
+
+<interval value expression 1> ::= <interval value expression>
+
+<interval term 1> ::= <interval term>
+
+<datetime term> ::=
+ <datetime factor>
+
+<datetime factor> ::=
+ <datetime primary> [ <time zone> ]
+
+<datetime primary> ::=
+ <value expression primary>
+ | <datetime value function>
+
+<time zone> ::=
+ AT <time zone specifier>
+
+<time zone specifier> ::=
+ LOCAL
+ | TIME ZONE <interval value expression>
+
+<length expression> ::=
+ <char length expression>
+ | <octet length expression>
+ | <bit length expression>
+
+<char length expression> ::=
+ { CHAR_LENGTH | CHARACTER_LENGTH }
+ <left paren> <string value expression> <right paren>
+
+<string value expression> ::=
+ <character value expression>
+ | <bit value expression>
+
+<octet length expression> ::=
+ OCTET_LENGTH <left paren> <string value expression> <right paren>
+
+<bit length expression> ::=
+ BIT_LENGTH <left paren> <string value expression> <right paren>
+
+<null specification> ::=
+ NULL
+
+<default specification> ::=
+ DEFAULT
+
+<row value constructor list> ::=
+ <row value constructor element>
+ [ { <comma> <row value constructor element> }... ]
+
+<row subquery> ::= <subquery>
+
+<comp op> ::=
+ <equals operator>
+ | <not equals operator>
+ | <less than operator>
+ | <greater than operator>
+ | <less than or equals operator>
+ | <greater than or equals operator>
+
+<between predicate> ::=
+ <row value constructor> [ NOT ] BETWEEN
+ <row value constructor> AND <row value constructor>
+
+<in predicate> ::=
+ <row value constructor>
+ [ NOT ] IN <in predicate value>
+
+<in predicate value> ::=
+ <table subquery>
+ | <left paren> <in value list> <right paren>
+
+<in value list> ::=
+ <value expression> { <comma> <value expression> }...
+
+<like predicate> ::=
+ <match value> [ NOT ] LIKE <pattern>
+ [ ESCAPE <escape character> ]
+
+<match value> ::= <character value expression>
+
+<pattern> ::= <character value expression>
+
+<escape character> ::= <character value expression>
+
+<null predicate> ::= <row value constructor>
+ IS [ NOT ] NULL
+
+<quantified comparison predicate> ::=
+ <row value constructor> <comp op> <quantifier> <table subquery>
+
+<quantifier> ::= <all> | <some>
+
+<all> ::= ALL
+
+<some> ::= SOME | ANY
+
+<exists predicate> ::= EXISTS <table subquery>
+
+<unique predicate> ::= UNIQUE <table subquery>
+
+<match predicate> ::=
+ <row value constructor> MATCH [ UNIQUE ]
+ [ PARTIAL | FULL ] <table subquery>
+
+<overlaps predicate> ::=
+ <row value constructor 1> OVERLAPS <row value constructor 2>
+
+<row value constructor 1> ::= <row value constructor>
+
+<row value constructor 2> ::= <row value constructor>
+
+<truth value> ::=
+ TRUE
+ | FALSE
+ | UNKNOWN
+
+<constraint attributes> ::=
+ <constraint check time> [ [ NOT ] DEFERRABLE ]
+ | [ NOT ] DEFERRABLE [ <constraint check time> ]
+
+<constraint check time> ::=
+ INITIALLY DEFERRED
+ | INITIALLY IMMEDIATE
+
+<table constraint definition> ::=
+ [ <constraint name definition> ]
+ <table constraint> [ <constraint attributes> ]
+
+<table constraint> ::=
+ <unique constraint definition>
+ | <referential constraint definition>
+ | <check constraint definition>
+
+<unique constraint definition> ::=
+ <unique specification> even in SQL3)
+ <unique specification>
+ <left paren> <unique column list> <right paren>
+
+<unique column list> ::= <column name list>
+
+<referential constraint definition> ::=
+ FOREIGN KEY
+ <left paren> <referencing columns> <right paren>
+ <references specification>
+
+<referencing columns> ::=
+ <reference column list>
+
+<module contents> ::=
+ <declare cursor>
+ | <dynamic declare cursor>
+ | <procedure>
+
+<declare cursor> ::=
+ DECLARE <cursor name> [ INSENSITIVE ] [ SCROLL ] CURSOR
+ FOR <cursor specification>
+
+<cursor name> ::= <identifier>
+
+<cursor specification> ::=
+ <query expression> [ <order by clause> ]
+ [ <updatability clause> ]
+
+<order by clause> ::=
+ ORDER BY <sort specification list>
+
+<sort specification list> ::=
+ <sort specification> [ { <comma> <sort specification> }... ]
+
+<sort specification> ::=
+ <sort key> [ <collate clause> ] [ <ordering specification> ]
+
+<sort key> ::=
+ <column name>
+ | <unsigned integer>
+
+<ordering specification> ::= ASC | DESC
+
+<updatability clause> ::=
+ FOR
+ { READ ONLY |
+ UPDATE [ OF <column name list> ] }
+
+<dynamic declare cursor> ::=
+ DECLARE <cursor name> [ INSENSITIVE ] [ SCROLL ] CURSOR
+ FOR <statement name>
+
+<statement name> ::= <identifier>
+
+<procedure> ::=
+ PROCEDURE <procedure name>
+ <parameter declaration list> <semicolon>
+ <SQL procedure statement> <semicolon>
+
+<procedure name> ::= <identifier>
+
+<parameter declaration list> ::=
+ <left paren> <parameter declaration>
+ [ { <comma> <parameter declaration> }... ] <right paren>
+ | <parameter declaration>...
+
+<parameter declaration> ::=
+ <parameter name> <data type>
+ | <status parameter>
+
+<status parameter> ::=
+ SQLCODE | SQLSTATE
+
+<SQL procedure statement> ::=
+ <SQL schema statement>
+ | <SQL data statement>
+ | <SQL transaction statement>
+ | <SQL connection statement>
+ | <SQL session statement>
+ | <SQL dynamic statement>
+ | <SQL diagnostics statement>
+
+<SQL schema statement> ::=
+ <SQL schema definition statement>
+ | <SQL schema manipulation statement>
+
+<SQL schema definition statement> ::=
+ <schema definition>
+ | <table definition>
+ | <view definition>
+ | <grant statement>
+ | <domain definition>
+ | <character set definition>
+ | <collation definition>
+ | <translation definition>
+ | <assertion definition>
+
+<schema definition> ::=
+ CREATE SCHEMA <schema name clause>
+ [ <schema character set specification> ]
+ [ <schema element>... ]
+
+<schema name clause> ::=
+ <schema name>
+ | AUTHORIZATION <schema authorization identifier>
+ | <schema name> AUTHORIZATION
+ <schema authorization identifier>
+
+<schema authorization identifier> ::=
+ <authorization identifier>
+
+<schema character set specification> ::=
+ DEFAULT CHARACTER
+ SET <character set specification>
+
+<schema element> ::=
+ <domain definition>
+ | <table definition>
+ | <view definition>
+ | <grant statement>
+ | <assertion definition>
+ | <character set definition>
+ | <collation definition>
+ | <translation definition>
+
+<domain definition> ::=
+ CREATE DOMAIN <domain name>
+ [ AS ] <data type>
+ [ <default clause> ]
+ [ <domain constraint>... ]
+ [ <collate clause> ]
+
+<domain constraint> ::=
+ [ <constraint name definition> ]
+ <check constraint definition> [ <constraint attributes> ]
+
+<table definition> ::=
+ CREATE [ { GLOBAL | LOCAL } TEMPORARY ] TABLE
+ <table name>
+ <table element list>
+ [ ON COMMIT { DELETE | PRESERVE } ROWS ]
+
+<view definition> ::=
+ CREATE VIEW <table name> [ <left paren> <view column list>
+ <right paren> ]
+ AS <query expression>
+ [ WITH [ <levels clause> ] CHECK OPTION ]
+
+<view column list> ::= <column name list>
+
+<levels clause> ::=
+ CASCADED | LOCAL
+
+<grant statement> ::=
+ GRANT <privileges> ON <object name>
+ TO <grantee> [ { <comma> <grantee> }... ]
+ [ WITH GRANT OPTION ]
+
+<privileges> ::=
+ ALL PRIVILEGES
+ | <action list>
+
+<action list> ::= <action> [ { <comma> <action> }... ]
+
+<action> ::=
+ SELECT
+ | DELETE
+ | INSERT [ <left paren> <privilege column list> <right paren> ]
+ | UPDATE [ <left paren> <privilege column list> <right paren> ]
+ | REFERENCES [ <left paren> <privilege column list> <right paren> ]
+ | USAGE
+
+<privilege column list> ::= <column name list>
+
+<object name> ::=
+ [ TABLE ] <table name>
+ | DOMAIN <domain name>
+ | COLLATION <collation name>
+ | CHARACTER SET <character set name>
+ | TRANSLATION <translation name>
+
+<grantee> ::=
+ PUBLIC
+ | <authorization identifier>
+
+<assertion definition> ::=
+ CREATE ASSERTION <constraint name> <assertion check>
+ [ <constraint attributes> ]
+
+<assertion check> ::=
+ CHECK
+ <left paren> <search condition> <right paren>
+
+<character set definition> ::=
+ CREATE CHARACTER SET <character set name>
+ [ AS ]
+ <character set source>
+ [ <collate clause> | <limited collation definition> ]
+
+<character set source> ::=
+ GET <existing character set name>
+
+<existing character set name> ::=
+ <standard character repertoire name>
+ | <implementation-defined character repertoire name>
+ | <schema character set name>
+
+<schema character set name> ::= <character set name>
+
+<limited collation definition> ::=
+ COLLATION FROM <collation source>
+
+<collation source> ::=
+ <collating sequence definition>
+ | <translation collation>
+
+<collating sequence definition> ::=
+ <external collation>
+ | <schema collation name>
+ | DESC <left paren> <collation name> <right paren>
+ | DEFAULT
+
+<external collation> ::=
+ EXTERNAL <left paren> <quote> <external collation name> <quote> <right paren>
+
+<external collation name> ::=
+ <standard collation name>
+ | <implementation-defined collation name>
+
+<standard collation name> ::= <collation name>
+
+<implementation-defined collation name> ::= <collation name>
+
+<schema collation name> ::= <collation name>
+
+<translation collation> ::=
+ TRANSLATION <translation name>
+ [ THEN COLLATION <collation name> ]
+
+<collation definition> ::=
+ CREATE COLLATION <collation name> FOR
+ <character set specification>
+ FROM <collation source>
+ [ <pad attribute> ]
+
+<pad attribute> ::=
+ NO PAD
+ | PAD SPACE
+
+<translation definition> ::=
+ CREATE TRANSLATION <translation name>
+ FOR <source character set specification>
+ TO <target character set specification>
+ FROM <translation source>
+
+<source character set specification> ::= <character set specification>
+
+<target character set specification> ::= <character set specification>
+
+<translation source> ::=
+ <translation specification>
+
+<translation specification> ::=
+ <external translation>
+ | IDENTITY
+ | <schema translation name>
+
+<external translation> ::=
+ EXTERNAL <left paren> <quote> <external translation name> <quote> <right paren>
+
+<external translation name> ::=
+ <standard translation name>
+ | <implementation-defined translation name>
+
+<standard translation name> ::= <translation name>
+
+<implementation-defined translation name> ::= <translation name>
+
+<schema translation name> ::= <translation name>
+
+<SQL schema manipulation statement> ::=
+ <drop schema statement>
+ | <alter table statement>
+ | <drop table statement>
+ | <drop view statement>
+ | <revoke statement>
+ | <alter domain statement>
+ | <drop domain statement>
+ | <drop character set statement>
+ | <drop collation statement>
+ | <drop translation statement>
+ | <drop assertion statement>
+
+<drop schema statement> ::=
+ DROP SCHEMA <schema name> <drop behavior>
+
+<drop behavior> ::= CASCADE | RESTRICT
+
+<alter table statement> ::=
+ ALTER TABLE <table name> <alter table action>
+
+<alter table action> ::=
+ <add column definition>
+ | <alter column definition>
+ | <drop column definition>
+ | <add table constraint definition>
+ | <drop table constraint definition>
+
+<add column definition> ::=
+ ADD [ COLUMN ] <column definition>
+
+<alter column definition> ::=
+ ALTER [ COLUMN ] <column name> <alter column action>
+
+<alter column action> ::=
+ <set column default clause>
+ | <drop column default clause>
+
+<set column default clause> ::=
+ SET <default clause>
+
+<drop column default clause> ::=
+ DROP DEFAULT
+
+<drop column definition> ::=
+ DROP [ COLUMN ] <column name> <drop behavior>
+
+<add table constraint definition> ::=
+ ADD <table constraint definition>
+
+<drop table constraint definition> ::=
+ DROP CONSTRAINT <constraint name> <drop behavior>
+
+<drop table statement> ::=
+ DROP TABLE <table name> <drop behavior>
+
+<drop view statement> ::=
+ DROP VIEW <table name> <drop behavior>
+
+<revoke statement> ::=
+ REVOKE [ GRANT OPTION FOR ]
+ <privileges>
+ ON <object name>
+ FROM <grantee> [ { <comma> <grantee> }... ] <drop behavior>
+
+<alter domain statement> ::=
+ ALTER DOMAIN <domain name> <alter domain action>
+
+<alter domain action> ::=
+ <set domain default clause>
+ | <drop domain default clause>
+ | <add domain constraint definition>
+ | <drop domain constraint definition>
+
+<set domain default clause> ::= SET <default clause>
+
+<drop domain default clause> ::= DROP DEFAULT
+
+<add domain constraint definition> ::=
+ ADD <domain constraint>
+
+<drop domain constraint definition> ::=
+ DROP CONSTRAINT <constraint name>
+
+<drop domain statement> ::=
+ DROP DOMAIN <domain name> <drop behavior>
+
+<drop character set statement> ::=
+ DROP CHARACTER SET <character set name>
+
+<drop collation statement> ::=
+ DROP COLLATION <collation name>
+
+<drop translation statement> ::=
+ DROP TRANSLATION <translation name>
+
+<drop assertion statement> ::=
+ DROP ASSERTION <constraint name>
+
+<SQL data statement> ::=
+ <open statement>
+ | <fetch statement>
+ | <close statement>
+ | <select statement: single row>
+ | <SQL data change statement>
+
+<open statement> ::=
+ OPEN <cursor name>
+
+<fetch statement> ::=
+ FETCH [ [ <fetch orientation> ] FROM ]
+ <cursor name> INTO <fetch target list>
+
+<fetch orientation> ::=
+ NEXT
+ | PRIOR
+ | FIRST
+ | LAST
+ | { ABSOLUTE | RELATIVE } <simple value specification>
+
+<simple value specification> ::=
+ <parameter name>
+ | <embedded variable name>
+ | <literal>
+
+<fetch target list> ::=
+ <target specification> [ { <comma> <target specification> }... ]
+
+<target specification> ::=
+ <parameter specification>
+ | <variable specification>
+
+<close statement> ::=
+ CLOSE <cursor name>
+
+<select statement: single row> ::=
+ SELECT [ <set quantifier> ] <select list>
+ INTO <select target list>
+ <table expression>
+
+<select target list> ::=
+ <target specification> [ { <comma> <target specification> }... ]
+
+<SQL data change statement> ::=
+ <delete statement: positioned>
+ | <delete statement: searched>
+ | <insert statement>
+ | <update statement: positioned>
+ | <update statement: searched>
+
+<delete statement: positioned> ::=
+ DELETE FROM <table name>
+ WHERE CURRENT OF <cursor name>
+
+<delete statement: searched> ::=
+ DELETE FROM <table name>
+ [ WHERE <search condition> ]
+
+<insert statement> ::=
+ INSERT INTO <table name>
+ <insert columns and source>
+
+<insert columns and source> ::=
+ [ <left paren> <insert column list> <right paren> ]
+ <query expression>
+ | DEFAULT VALUES
+
+<insert column list> ::= <column name list>
+
+<update statement: positioned> ::=
+ UPDATE <table name>
+ SET <set clause list>
+ WHERE CURRENT OF <cursor name>
+
+<set clause list> ::=
+ <set clause> [ { <comma> <set clause> }... ]
+
+<set clause> ::=
+ <object column> <equals operator> <update source>
+
+<object column> ::= <column name>
+
+<update source> ::=
+ <value expression>
+ | <null specification>
+ | DEFAULT
+
+<update statement: searched> ::=
+ UPDATE <table name>
+ SET <set clause list>
+ [ WHERE <search condition> ]
+
+<SQL transaction statement> ::=
+ <set transaction statement>
+ | <set constraints mode statement>
+ | <commit statement>
+ | <rollback statement>
+
+<set transaction statement> ::=
+ SET TRANSACTION <transaction mode>
+ [ { <comma> <transaction mode> }... ]
+
+<transaction mode> ::=
+ <isolation level>
+ | <transaction access mode>
+ | <diagnostics size>
+
+<isolation level> ::=
+ ISOLATION LEVEL <level of isolation>
+
+<level of isolation> ::=
+ READ UNCOMMITTED
+ | READ COMMITTED
+ | REPEATABLE READ
+ | SERIALIZABLE
+
+<transaction access mode> ::=
+ READ ONLY
+ | READ WRITE
+
+<diagnostics size> ::=
+ DIAGNOSTICS SIZE <number of conditions>
+
+<number of conditions> ::= <simple value specification>
+
+<set constraints mode statement> ::=
+ SET CONSTRAINTS <constraint name list>
+ { DEFERRED | IMMEDIATE }
+
+<constraint name list> ::=
+ ALL
+ | <constraint name> [ { <comma> <constraint name> }... ]
+
+<commit statement> ::=
+ COMMIT [ WORK ]
+
+<rollback statement> ::=
+ ROLLBACK [ WORK ]
+
+<SQL connection statement> ::=
+ <connect statement>
+ | <set connection statement>
+ | <disconnect statement>
+
+<connect statement> ::=
+ CONNECT TO <connection target>
+
+<connection target> ::=
+ <SQL-server name>
+ [ AS <connection name> ]
+ correspondence with Tony Gordon)
+ [ USER <user name> ]
+ | DEFAULT
+
+<SQL-server name> ::= <simple value specification>
+
+<connection name> ::= <simple value specification>
+
+<user name> ::= <simple value specification>
+
+<set connection statement> ::=
+ SET CONNECTION <connection object>
+
+<connection object> ::=
+ DEFAULT
+ | <connection name>
+
+<disconnect statement> ::=
+ DISCONNECT <disconnect object>
+
+<disconnect object> ::=
+ <connection object>
+ | ALL
+ | CURRENT
+
+<SQL session statement> ::=
+ <set catalog statement>
+ | <set schema statement>
+ | <set names statement>
+ | <set session authorization identifier statement>
+ | <set local time zone statement>
+
+<set catalog statement> ::=
+ SET CATALOG <value specification>
+
+<value specification> ::=
+ <literal>
+ | <general value specification>
+
+<set schema statement> ::=
+ SET SCHEMA <value specification>
+
+<set names statement> ::=
+ SET NAMES <value specification>
+
+<set session authorization identifier statement> ::=
+ SET SESSION AUTHORIZATION
+ <value specification>
+
+<set local time zone statement> ::=
+ SET TIME ZONE
+ <set time zone value>
+
+<set time zone value> ::=
+ <interval value expression>
+ | LOCAL
+
+<SQL dynamic statement> ::=
+ <system descriptor statement>
+ | <prepare statement>
+ | <deallocate prepared statement>
+ | <describe statement>
+ | <execute statement>
+ | <execute immediate statement>
+ | <SQL dynamic data statement>
+
+<system descriptor statement> ::=
+ <allocate descriptor statement>
+ | <deallocate descriptor statement>
+ | <set descriptor statement>
+ | <get descriptor statement>
+
+<allocate descriptor statement> ::=
+ ALLOCATE DESCRIPTOR <descriptor name>
+ [ WITH MAX <occurrences> ]
+
+<descriptor name> ::=
+ [ <scope option> ] <simple value specification>
+
+<scope option> ::=
+ GLOBAL
+ | LOCAL
+
+<occurrences> ::= <simple value specification>
+
+<deallocate descriptor statement> ::=
+ DEALLOCATE DESCRIPTOR <descriptor name>
+
+<set descriptor statement> ::=
+ SET DESCRIPTOR <descriptor name>
+ <set descriptor information>
+
+<set descriptor information> ::=
+ <set count>
+ | VALUE <item number>
+ <set item information> [ { <comma> <set item information> }... ]
+
+<set count> ::=
+ COUNT <equals operator> <simple value specification 1>
+
+<simple value specification 1> ::= <simple value specification>
+
+<item number> ::= <simple value specification>
+
+<set item information> ::=
+ <descriptor item name> <equals operator> <simple value specification 2>
+
+<descriptor item name> ::=
+ TYPE
+ | LENGTH
+ | OCTET_LENGTH
+ | RETURNED_LENGTH
+ | RETURNED_OCTET_LENGTH
+ | PRECISION
+ | SCALE
+ | DATETIME_INTERVAL_CODE
+ | DATETIME_INTERVAL_PRECISION
+ | NULLABLE
+ | INDICATOR
+ | DATA
+ | NAME
+ | UNNAMED
+ | COLLATION_CATALOG
+ | COLLATION_SCHEMA
+ | COLLATION_NAME
+ | CHARACTER_SET_CATALOG
+ | CHARACTER_SET_SCHEMA
+ | CHARACTER_SET_NAME
+
+<simple value specification 2> ::= <simple value specification>
+
+<item number> ::= <simple value specification>
+
+<get descriptor statement> ::=
+ GET DESCRIPTOR <descriptor name> <get descriptor information>
+
+<get descriptor information> ::=
+ <get count>
+ | VALUE <item number>
+ <get item information> [ { <comma> <get item information> }... ]
+
+<get count> ::=
+ <simple target specification 1> <equals operator>
+ COUNT
+
+<simple target specification 1> ::= <simple target specification>
+
+<simple target specification> ::=
+ <parameter name>
+ | <embedded variable name>
+
+<get item information> ::=
+ <simple target specification 2> <equals operator> <descriptor item name>>
+
+<simple target specification 2> ::= <simple target specification>
+
+<prepare statement> ::=
+ PREPARE <SQL statement name> FROM <SQL statement variable>
+
+<SQL statement name> ::=
+ <statement name>
+ | <extended statement name>
+
+<extended statement name> ::=
+ [ <scope option> ] <simple value specification>
+
+<SQL statement variable> ::= <simple value specification>
+
+<deallocate prepared statement> ::=
+ DEALLOCATE PREPARE <SQL statement name>
+
+<describe statement> ::=
+ <describe input statement>
+ | <describe output statement>
+
+<describe input statement> ::=
+ DESCRIBE INPUT <SQL statement name> <using descriptor>
+
+<using descriptor> ::=
+ { USING | INTO } SQL DESCRIPTOR <descriptor name>
+
+<describe output statement> ::=
+ DESCRIBE [ OUTPUT ] <SQL statement name> <using descriptor>
+
+<execute statement> ::=
+ EXECUTE <SQL statement name>
+ [ <result using clause> ]
+ [ <parameter using clause> ]
+
+<result using clause> ::= <using clause>
+
+<using clause> ::=
+ <using arguments>
+ | <using descriptor>
+
+<using arguments> ::=
+ { USING | INTO } <argument> [ { <comma> <argument> }... ]
+
+<argument> ::= <target specification>
+
+<parameter using clause> ::= <using clause>
+
+<execute immediate statement> ::=
+ EXECUTE IMMEDIATE <SQL statement variable>
+
+<SQL dynamic data statement> ::=
+ <allocate cursor statement>
+ | <dynamic open statement>
+ | <dynamic fetch statement>
+ | <dynamic close statement>
+ | <dynamic delete statement: positioned>
+ | <dynamic update statement: positioned>
+
+<allocate cursor statement> ::=
+ ALLOCATE <extended cursor name> [ INSENSITIVE ]
+ [ SCROLL ] CURSOR
+ FOR <extended statement name>
+
+<extended cursor name> ::=
+ [ <scope option> ] <simple value specification>
+
+<dynamic open statement> ::=
+ OPEN <dynamic cursor name> [ <using clause> ]
+
+<dynamic cursor name> ::=
+ <cursor name>
+ | <extended cursor name>
+
+<dynamic fetch statement> ::=
+ FETCH [ [ <fetch orientation> ] FROM ] <dynamic cursor name>
+ <using clause>
+
+<dynamic close statement> ::=
+ CLOSE <dynamic cursor name>
+
+<dynamic delete statement: positioned> ::=
+ DELETE FROM <table name>
+ WHERE CURRENT OF
+ <dynamic cursor name>
+
+<dynamic update statement: positioned> ::=
+ UPDATE <table name>
+ SET <set clause>
+ [ { <comma> <set clause> }... ]
+ WHERE CURRENT OF
+ <dynamic cursor name>
+
+<SQL diagnostics statement> ::=
+ <get diagnostics statement>
+
+<get diagnostics statement> ::=
+ GET DIAGNOSTICS <sql diagnostics information>
+
+<sql diagnostics information> ::=
+ <statement information>
+ | <condition information>
+
+<statement information> ::=
+ <statement information item> [ { <comma> <statement information item> }... ]
+
+<statement information item> ::=
+ <simple target specification> <equals operator> <statement information item name>
+
+<statement information item name> ::=
+ NUMBER
+ | MORE
+ | COMMAND_FUNCTION
+ | DYNAMIC_FUNCTION
+ | ROW_COUNT
+
+<condition information> ::=
+ EXCEPTION <condition number>
+ <condition information item> [ { <comma> <condition information item> }... ]
+
+<condition number> ::= <simple value specification>
+
+<condition information item> ::=
+ <simple target specification> <equals operator> <condition information item name>
+
+<condition information item name> ::=
+ CONDITION_NUMBER
+ | RETURNED_SQLSTATE
+ | CLASS_ORIGIN
+ | SUBCLASS_ORIGIN
+ | SERVER_NAME
+ | CONNECTION_NAME
+ | CONSTRAINT_CATALOG
+ | CONSTRAINT_SCHEMA
+ | CONSTRAINT_NAME
+ | CATALOG_NAME
+ | SCHEMA_NAME
+ | TABLE_NAME
+ | COLUMN_NAME
+ | CURSOR_NAME
+ | MESSAGE_TEXT
+ | MESSAGE_LENGTH
+ | MESSAGE_OCTET_LENGTH
+
+<embedded SQL host program> ::=
+ <embedded SQL Ada program>
+ | <embedded SQL C program>
+ | <embedded SQL COBOL program>
+ | <embedded SQL Fortran program>
+ | <embedded SQL MUMPS program>
+ | <embedded SQL Pascal program>
+ | <embedded SQL PL/I program>
+
+<embedded SQL Ada program> ::= !! <EMPHASIS>(See the Syntax Rules.)
+
+<embedded SQL C program> ::=
+ !! <EMPHASIS>(See the Syntax Rules.)
+
+<embedded SQL COBOL program> ::= !! <EMPHASIS>(See the Syntax Rules.)
+
+<embedded SQL Fortran program> ::=
+ !! <EMPHASIS>(See the Syntax Rules.)
+
+<embedded SQL MUMPS program> ::= !! <EMPHASIS>(See the Syntax Rules.)
+
+<embedded SQL Pascal program> ::=
+ !! <EMPHASIS>(See the Syntax Rules.)
+
+<embedded SQL PL/I program> ::= !! <EMPHASIS>(See the Syntax Rules.)
+
+<embedded SQL declare section> ::=
+ <embedded SQL begin declare>
+ [ <embedded character set declaration> ]
+ [ <host variable definition>... ]
+ <embedded SQL end declare>
+ | <embedded SQL MUMPS declare>
+
+<embedded SQL begin declare> ::=
+ <SQL prefix> BEGIN DECLARE SECTION
+ [ <SQL terminator> ]
+
+<SQL prefix> ::=
+ EXEC SQL
+ | <ampersand>SQL<left paren>
+
+<SQL terminator> ::=
+ END-EXEC
+ | <semicolon>
+ | <right paren>
+
+<embedded character set declaration> ::=
+ SQL NAMES ARE <character set specification>
+
+<host variable definition> ::=
+ <Ada variable definition>
+ | <C variable definition>
+ | <COBOL variable definition>
+ | <Fortran variable definition>
+ | <MUMPS variable definition>
+ | <Pascal variable definition>
+ | <PL/I variable definition>
+
+<Ada variable definition> ::=
+ <Ada host identifier> [ { <comma> <Ada host identifier> }... ] :
+ <Ada type specification> [ <Ada initial value> ]
+
+<Ada type specification> ::=
+ <Ada qualified type specification>
+ | <Ada unqualified type specification>
+
+<Ada qualified type specification> ::=
+ SQL_STANDARD.CHAR [ CHARACTER SET
+ [ IS ] <character set specification> ]
+ <left paren> 1 <double period> <length> <right paren>
+ | SQL_STANDARD.BIT
+ <left paren> 1 <double period> <length> <right paren>
+ | SQL_STANDARD.SMALLINT
+ | SQL_STANDARD.INT
+ | SQL_STANDARD.REAL
+ | SQL_STANDARD.DOUBLE_PRECISION
+ | SQL_STANDARD.SQLCODE_TYPE
+ | SQL_STANDARD.SQLSTATE_TYPE
+ | SQL_STANDARD.INDICATOR_TYPE
+
+<Ada unqualified type specification> ::=
+ CHAR
+ <left paren> 1 <double period> <length> <right paren>
+ | BIT
+ <left paren> 1 <double period> <length> <right paren>
+ | SMALLINT
+ | INT
+ | REAL
+ | DOUBLE_PRECISION
+ | SQLCODE_TYPE
+ | SQLSTATE_TYPE
+ | INDICATOR_TYPE
+
+<Ada initial value> ::=
+ <Ada assignment operator> <character representation>...
+
+<Ada assignment operator> ::= <colon><equals operator>
+
+<C variable definition> ::=
+ [ <C storage class> ]
+ [ <C class modifier> ]
+ <C variable specification>
+ <semicolon>
+
+<C storage class> ::=
+ auto
+ | extern
+ | static
+
+<C class modifier> ::= const | volatile
+
+<C variable specification> ::=
+ <C numeric variable>
+ | <C character variable>
+ | <C derived variable>
+
+<C numeric variable> ::=
+ { long | short | float | double }
+ <C host identifier> [ <C initial value> ]
+ [ { <comma> <C host identifier> [ <C initial value> ] }... ]
+
+<C initial value> ::=
+ <equals operator> <character representation>...
+
+<C character variable> ::=
+ char [ CHARACTER SET
+ [ IS ] <character set specification> ]
+ <C host identifier>
+ <C array specification> [ <C initial value> ]
+ [ { <comma> <C host identifier>
+ <C array specification>
+ [ <C initial value> ] }... ]
+
+<C array specification> ::=
+ <left bracket> <length> <right bracket>
+
+<C derived variable> ::=
+ <C VARCHAR variable>
+ | <C bit variable>
+
+<C VARCHAR variable> ::=
+ VARCHAR [ CHARACTER SET [ IS ]
+ <character set specification> ]
+ <C host identifier>
+ <C array specification> [ <C initial value> ]
+ [ { <comma> <C host identifier>
+ <C array specification>
+ [ <C initial value> ] }... ]
+
+<C bit variable> ::=
+ BIT <C host identifier>
+ <C array specification> [ <C initial value> ]
+ [ { <comma> <C host identifier>
+ <C array specification>
+ [ <C initial value> ] }... ]
+
+<COBOL variable definition> ::=
+ {01|77} <COBOL host identifier> <COBOL type specification>
+ [ <character representation>... ] <period>
+
+<COBOL type specification> ::=
+ <COBOL character type>
+ | <COBOL bit type>
+ | <COBOL numeric type>
+ | <COBOL integer type>
+
+<COBOL character type> ::=
+ [ CHARACTER SET [ IS ]
+ <character set specification> ]
+ { PIC | PICTURE } [ IS ] { X [ <left paren> <length> <right paren> ] }...
+
+<COBOL bit type> ::=
+ { PIC | PICTURE } [ IS ]
+ { B [ <left paren> <length> <right paren> ] }...
+
+<COBOL numeric type> ::=
+ { PIC | PICTURE } [ IS ]
+ S <COBOL nines specification>
+ [ USAGE [ IS ] ] DISPLAY SIGN LEADING SEPARATE
+
+<COBOL nines specification> ::=
+ <COBOL nines> [ V [ <COBOL nines> ] ]
+ | V <COBOL nines>
+
+<COBOL nines> ::= { 9 [ <left paren> <length> <right paren> ] }...
+
+<COBOL integer type> ::=
+ <COBOL computational integer>
+ | <COBOL binary integer>
+
+<COBOL computational integer> ::=
+ { PIC | PICTURE } [ IS ] S<COBOL nines>
+ [ USAGE [ IS ] ] { COMP | COMPUTATIONAL }
+
+<COBOL binary integer> ::=
+ { PIC | PICTURE } [ IS ] S<COBOL nines>
+ [ USAGE [ IS ] ] BINARY
+
+<Fortran variable definition> ::=
+ <Fortran type specification>
+ <Fortran host identifier>
+ [ { <comma> <Fortran host identifier> }... ]
+
+<Fortran type specification> ::=
+ CHARACTER [ <asterisk> <length> ]
+ [ CHARACTER SET [ IS ]
+ <character set specification> ]
+ | BIT [ <asterisk> <length> ]
+ | INTEGER
+ | REAL
+ | DOUBLE PRECISION
+
+<MUMPS variable definition> ::=
+ { <MUMPS numeric variable> | <MUMPS character variable> }
+ <semicolon>
+
+<MUMPS numeric variable> ::=
+ <MUMPS type specification>
+ <MUMPS host identifier> [ { <comma> <MUMPS host identifier> }... ]
+
+<MUMPS type specification> ::=
+ INT
+ | DEC
+ [ <left paren> <precision> [ <comma> <scale> ] <right paren> ]
+ | REAL
+
+<MUMPS character variable> ::=
+ VARCHAR <MUMPS host identifier> <MUMPS length specification>
+ [ { <comma> <MUMPS host identifier> <MUMPS length specification> }... ]
+
+<MUMPS length specification> ::=
+ <left paren> <length> <right paren>
+
+<Pascal variable definition> ::=
+ <Pascal host identifier> [ { <comma> <Pascal host identifier> }... ] <colon>
+ <Pascal type specification> <semicolon>
+
+<Pascal type specification> ::=
+ PACKED ARRAY
+ <left bracket> 1 <double period> <length> <right bracket>
+ OF CHAR
+ [ CHARACTER SET [ IS ]
+ <character set specification> ]
+ | PACKED ARRAY
+ <left bracket> 1 <double period> <length> <right bracket>
+ OF BIT
+ | INTEGER
+ | REAL
+ | CHAR [ CHARACTER SET
+ [ IS ] <character set specification> ]
+ | BIT
+
+<PL/I variable definition> ::=
+ {DCL | DECLARE}
+ { <PL/I host identifier>
+ | <left paren> <PL/I host identifier>
+ [ { <comma> <PL/I host identifier> }... ] <right paren> }
+ <PL/I type specification>
+ [ <character representation>... ] <semicolon>
+
+<PL/I type specification> ::=
+ { CHAR | CHARACTER } [ VARYING ]
+ <left paren><length><right paren>
+ [ CHARACTER SET
+ [ IS ] <character set specification> ]
+ | BIT [ VARYING ] <left paren><length><right paren>
+ | <PL/I type fixed decimal> <left paren> <precision>
+ [ <comma> <scale> ] <right paren>
+ | <PL/I type fixed binary> [ <left paren> <precision> <right paren> ]
+ | <PL/I type float binary> <left paren> <precision> <right paren>
+
+<PL/I type fixed decimal> ::=
+ { DEC | DECIMAL } FIXED
+ | FIXED { DEC | DECIMAL }
+
+<PL/I type fixed binary> ::=
+ { BIN | BINARY } FIXED
+ | FIXED { BIN | BINARY }
+
+<PL/I type float binary> ::=
+ { BIN | BINARY } FLOAT
+ | FLOAT { BIN | BINARY }
+
+<embedded SQL end declare> ::=
+ <SQL prefix> END DECLARE SECTION
+ [ <SQL terminator> ]
+
+<embedded SQL MUMPS declare> ::=
+ <SQL prefix>
+ BEGIN DECLARE SECTION
+ [ <embedded character set declaration> ]
+ [ <host variable definition>... ]
+ END DECLARE SECTION
+ <SQL terminator>
+
+<embedded SQL statement> ::=
+ <SQL prefix>
+ <statement or declaration>
+ [ <SQL terminator> ]
+
+<statement or declaration> ::=
+ <declare cursor>
+ | <dynamic declare cursor>
+ | <temporary table declaration>
+ | <embedded exception declaration>
+ | <SQL procedure statement>
+
+<embedded exception declaration> ::=
+ WHENEVER <condition> <condition action>
+
+<condition> ::=
+ SQLERROR | NOT FOUND
+
+<condition action> ::=
+ CONTINUE | <go to>
+
+<go to> ::=
+ { GOTO | GO TO } <goto target>
+
+<goto target> ::=
+ <host label identifier>
+ | <unsigned integer>
+ | <host PL/I label variable>
+
+<host label identifier> ::= !!<EMPHASIS>(See the Syntax Rules.)
+
+<host PL/I label variable> ::= !!<EMPHASIS>(See the Syntax Rules.)
+
+<preparable statement> ::=
+ <preparable SQL data statement>
+ | <preparable SQL schema statement>
+ | <preparable SQL transaction statement>
+ | <preparable SQL session statement>
+ | <preparable implementation-defined statement>
+
+<preparable SQL data statement> ::=
+ <delete statement: searched>
+ | <dynamic single row select statement>
+ | <insert statement>
+ | <dynamic select statement>
+ | <update statement: searched>
+ | <preparable dynamic delete statement: positioned>
+ | <preparable dynamic update statement: positioned>
+
+<dynamic single row select statement> ::= <query specification>
+
+<dynamic select statement> ::= <cursor specification>
+
+<preparable dynamic delete statement: positioned> ::=
+ DELETE [ FROM <table name> ]
+ WHERE CURRENT OF <cursor name>
+
+<preparable dynamic update statement: positioned> ::=
+ UPDATE [ <table name> ]
+ SET <set clause list>
+ WHERE CURRENT OF <cursor name>
+
+<preparable SQL schema statement> ::=
+ <SQL schema statement>
+
+<preparable SQL transaction statement> ::=
+ <SQL transaction statement>
+
+<preparable SQL session statement> ::=
+ <SQL session statement>
+
+<preparable implementation-defined statement> ::=
+ !! <EMPHASIS>(See the Syntax Rules.)
+
+<direct SQL statement> ::=
+ <directly executable statement> <semicolon>
+
+<directly executable statement> ::=
+ <direct SQL data statement>
+ | <SQL schema statement>
+ | <SQL transaction statement>
+ | <SQL connection statement>
+ | <SQL session statement>
+ | <direct implementation-defined statement>
+
+<direct SQL data statement> ::=
+ <delete statement: searched>
+ | <direct select statement: multiple rows>
+ | <insert statement>
+ | <update statement: searched>
+ | <temporary table declaration>
+
+<direct select statement: multiple rows> ::=
+ <query expression> [ <order by clause> ]
+
+<direct implementation-defined statement> ::=
+ !!<EMPHASIS>(See the Syntax Rules)
+
+<SQL object identifier> ::=
+ <SQL provenance> <SQL variant>
+
+<SQL provenance> ::= <arc1> <arc2> <arc3>
+
+<arc1> ::= iso | 1 | iso <left paren> 1 <right paren>
+
+<arc2> ::= standard | 0 | standard <left paren> 0 <right paren>
+
+<arc3> ::= 9075
+
+<SQL variant> ::= <SQL edition> <SQL conformance>
+
+<SQL edition> ::= <1987> | <1989> | <1992>
+
+<1987> ::= 0 | edition1987 <left paren> 0 <right paren>
+
+<1989> ::= <1989 base> <1989 package>
+
+<1989 base> ::= 1 | edition1989 <left paren> 1 <right paren>
+
+<1989 package> ::= <integrity no> | <integrity yes>
+
+<integrity no> ::= 0 | IntegrityNo <left paren> 0 <right paren>
+
+<integrity yes> ::= 1 | IntegrityYes <left paren> 1 <right paren>
+
+<1992> ::= 2 | edition1992 <left paren> 2 <right paren>
+
+<SQL conformance> ::= <low> | <intermediate> | <high>
+
+<low> ::= 0 | Low <left paren> 0 <right paren>
+
+<intermediate> ::= 1 | Intermediate <left paren> 1 <right paren>
+
+<high> ::= 2 | High <left paren> 2 <right paren>
+
Property changes on: branches/ddl_sequencer/extensions/dna-sequencer-ddl/src/test/resources/sql2bnf.aug92.txt
___________________________________________________________________
Name: svn:mime-type
+ text/plain
Added: branches/ddl_sequencer/extensions/dna-sequencer-ddl/target/classes/org/jboss/dna/sequencer/ddl/DdlConstants$DataTypes.class
===================================================================
(Binary files differ)
Property changes on: branches/ddl_sequencer/extensions/dna-sequencer-ddl/target/classes/org/jboss/dna/sequencer/ddl/DdlConstants$DataTypes.class
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: branches/ddl_sequencer/extensions/dna-sequencer-ddl/target/classes/org/jboss/dna/sequencer/ddl/DdlConstants$StatementStartPhrases.class
===================================================================
(Binary files differ)
Property changes on: branches/ddl_sequencer/extensions/dna-sequencer-ddl/target/classes/org/jboss/dna/sequencer/ddl/DdlConstants$StatementStartPhrases.class
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: branches/ddl_sequencer/extensions/dna-sequencer-ddl/target/classes/org/jboss/dna/sequencer/ddl/DdlConstants.class
===================================================================
(Binary files differ)
Property changes on: branches/ddl_sequencer/extensions/dna-sequencer-ddl/target/classes/org/jboss/dna/sequencer/ddl/DdlConstants.class
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: branches/ddl_sequencer/extensions/dna-sequencer-ddl/target/classes/org/jboss/dna/sequencer/ddl/DdlTokenStream$DdlTokenizer.class
===================================================================
(Binary files differ)
Property changes on: branches/ddl_sequencer/extensions/dna-sequencer-ddl/target/classes/org/jboss/dna/sequencer/ddl/DdlTokenStream$DdlTokenizer.class
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: branches/ddl_sequencer/extensions/dna-sequencer-ddl/target/classes/org/jboss/dna/sequencer/ddl/DdlTokenStream.class
===================================================================
(Binary files differ)
Property changes on: branches/ddl_sequencer/extensions/dna-sequencer-ddl/target/classes/org/jboss/dna/sequencer/ddl/DdlTokenStream.class
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: branches/ddl_sequencer/extensions/dna-sequencer-ddl/target/classes/org/jboss/dna/sequencer/ddl/OldDdlTokenizer.class
===================================================================
(Binary files differ)
Property changes on: branches/ddl_sequencer/extensions/dna-sequencer-ddl/target/classes/org/jboss/dna/sequencer/ddl/OldDdlTokenizer.class
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: branches/ddl_sequencer/extensions/dna-sequencer-ddl/target/classes/org/jboss/dna/sequencer/ddl/StandardDdlParser.class
===================================================================
(Binary files differ)
Property changes on: branches/ddl_sequencer/extensions/dna-sequencer-ddl/target/classes/org/jboss/dna/sequencer/ddl/StandardDdlParser.class
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: branches/ddl_sequencer/extensions/dna-sequencer-ddl/target/classes/org/jboss/dna/sequencer/ddl/dialect/Db2DdlParser.class
===================================================================
(Binary files differ)
Property changes on: branches/ddl_sequencer/extensions/dna-sequencer-ddl/target/classes/org/jboss/dna/sequencer/ddl/dialect/Db2DdlParser.class
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: branches/ddl_sequencer/extensions/dna-sequencer-ddl/target/classes/org/jboss/dna/sequencer/ddl/dialect/DerbyDdlParser$DerbyDataTypeParser.class
===================================================================
(Binary files differ)
Property changes on: branches/ddl_sequencer/extensions/dna-sequencer-ddl/target/classes/org/jboss/dna/sequencer/ddl/dialect/DerbyDdlParser$DerbyDataTypeParser.class
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: branches/ddl_sequencer/extensions/dna-sequencer-ddl/target/classes/org/jboss/dna/sequencer/ddl/dialect/DerbyDdlParser.class
===================================================================
(Binary files differ)
Property changes on: branches/ddl_sequencer/extensions/dna-sequencer-ddl/target/classes/org/jboss/dna/sequencer/ddl/dialect/DerbyDdlParser.class
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: branches/ddl_sequencer/extensions/dna-sequencer-ddl/target/classes/org/jboss/dna/sequencer/ddl/dialect/MySqlDdlParser$MySqlDataTypeParser.class
===================================================================
(Binary files differ)
Property changes on: branches/ddl_sequencer/extensions/dna-sequencer-ddl/target/classes/org/jboss/dna/sequencer/ddl/dialect/MySqlDdlParser$MySqlDataTypeParser.class
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: branches/ddl_sequencer/extensions/dna-sequencer-ddl/target/classes/org/jboss/dna/sequencer/ddl/dialect/MySqlDdlParser.class
===================================================================
(Binary files differ)
Property changes on: branches/ddl_sequencer/extensions/dna-sequencer-ddl/target/classes/org/jboss/dna/sequencer/ddl/dialect/MySqlDdlParser.class
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: branches/ddl_sequencer/extensions/dna-sequencer-ddl/target/classes/org/jboss/dna/sequencer/ddl/dialect/PostgresDdlParser.class
===================================================================
(Binary files differ)
Property changes on: branches/ddl_sequencer/extensions/dna-sequencer-ddl/target/classes/org/jboss/dna/sequencer/ddl/dialect/PostgresDdlParser.class
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: branches/ddl_sequencer/extensions/dna-sequencer-ddl/target/classes/org/jboss/dna/sequencer/ddl/dialect/SqlServerDdlParser.class
===================================================================
(Binary files differ)
Property changes on: branches/ddl_sequencer/extensions/dna-sequencer-ddl/target/classes/org/jboss/dna/sequencer/ddl/dialect/SqlServerDdlParser.class
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: branches/ddl_sequencer/extensions/dna-sequencer-ddl/target/classes/org/jboss/dna/sequencer/ddl/dialect/SybaseDdlParser.class
===================================================================
(Binary files differ)
Property changes on: branches/ddl_sequencer/extensions/dna-sequencer-ddl/target/classes/org/jboss/dna/sequencer/ddl/dialect/SybaseDdlParser.class
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: branches/ddl_sequencer/extensions/dna-sequencer-ddl/target/classes/sql2bnf.aug92.txt
===================================================================
--- branches/ddl_sequencer/extensions/dna-sequencer-ddl/target/classes/sql2bnf.aug92.txt (rev 0)
+++ branches/ddl_sequencer/extensions/dna-sequencer-ddl/target/classes/sql2bnf.aug92.txt 2009-10-02 16:13:40 UTC (rev 1280)
@@ -0,0 +1,2594 @@
+This file contains a depth-first tree traversal of the BNF
+for the language done at about 27-AUG-1992 11:03:41.64.
+The specific version of the BNF included here is: ANSI-only, SQL2-only.
+
+
+<SQL terminal character> ::=
+ <SQL language character>
+ | <SQL embedded language character>
+
+<SQL language character> ::=
+ <simple Latin letter>
+ | <digit>
+ | <SQL special character>
+
+<simple Latin letter> ::=
+ <simple Latin upper case letter>
+ | <simple Latin lower case letter>
+
+<simple Latin upper case letter> ::=
+ A | B | C | D | E | F | G | H | I | J | K | L | M | N | O
+ | P | Q | R | S | T | U | V | W | X | Y | Z
+
+<simple Latin lower case letter> ::=
+ a | b | c | d | e | f | g | h | i | j | k | l | m | n | o
+ | p | q | r | s | t | u | v | w | x | y | z
+
+<digit> ::=
+ 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9
+
+<SQL special character> ::=
+ <space>
+ | <double quote>
+ | <percent>
+ | <ampersand>
+ | <quote>
+ | <left paren>
+ | <right paren>
+ | <asterisk>
+ | <plus sign>
+ | <comma>
+ | <minus sign>
+ | <period>
+ | <solidus>
+ | <colon>
+ | <semicolon>
+ | <less than operator>
+ | <equals operator>
+ | <greater than operator>
+ | <question mark>
+ | <underscore>
+ | <vertical bar>
+
+<space> ::= !! <EMPHASIS>(space character in character set in use)
+
+<double quote> ::= "
+
+<percent> ::= %
+
+<ampersand> ::= &
+
+<quote> ::= '
+
+<left paren> ::= (
+
+<right paren> ::= )
+
+<asterisk> ::= *
+
+<plus sign> ::= +
+
+<comma> ::= ,
+
+<minus sign> ::= -
+
+<period> ::= .
+
+<solidus> ::= /
+
+<colon> ::= :
+
+<semicolon> ::= ;
+
+<less than operator> ::= <
+
+<equals operator> ::= =
+
+<greater than operator> ::= >
+
+<question mark> ::= ?
+
+<underscore> ::= _
+
+<vertical bar> ::= |
+
+<SQL embedded language character> ::=
+ <left bracket>
+ | <right bracket>
+
+<left bracket> ::= [
+
+<right bracket> ::= ]
+
+<token> ::=
+ <nondelimiter token>
+ | <delimiter token>
+
+<nondelimiter token> ::=
+ <regular identifier>
+ | <key word>
+ | <unsigned numeric literal>
+ | <national character string literal>
+ | <bit string literal>
+ | <hex string literal>
+
+<regular identifier> ::= <identifier body>
+
+<identifier body> ::=
+ <identifier start> [ { <underscore> | <identifier part> }... ]
+
+<identifier start> ::= <EMPHASIS>(!! See the Syntax Rules)
+
+<identifier part> ::=
+ <identifier start>
+ | <digit>
+
+<key word> ::=
+ <reserved word>
+ | <non-reserved word>
+
+<reserved word> ::=
+ ABSOLUTE | ACTION | ADD | ALL
+ | ALLOCATE | ALTER | AND
+ | ANY | ARE
+ | AS | ASC
+ | ASSERTION | AT
+ | AUTHORIZATION | AVG
+ | BEGIN | BETWEEN | BIT | BIT_LENGTH
+ | BOTH | BY
+ | CASCADE | CASCADED | CASE | CAST
+ | CATALOG
+ | CHAR | CHARACTER | CHAR_LENGTH
+ | CHARACTER_LENGTH | CHECK | CLOSE | COALESCE
+ | COLLATE | COLLATION
+ | COLUMN | COMMIT
+ | CONNECT
+ | CONNECTION | CONSTRAINT
+ | CONSTRAINTS | CONTINUE
+ | CONVERT | CORRESPONDING | COUNT | CREATE | CROSS
+ | CURRENT
+ | CURRENT_DATE | CURRENT_TIME
+ | CURRENT_TIMESTAMP | CURRENT_USER | CURSOR
+ | DATE | DAY | DEALLOCATE | DEC
+ | DECIMAL | DECLARE | DEFAULT | DEFERRABLE
+ | DEFERRED | DELETE | DESC | DESCRIBE | DESCRIPTOR
+ | DIAGNOSTICS
+ | DISCONNECT | DISTINCT | DOMAIN | DOUBLE | DROP
+ | ELSE | END | END-EXEC | ESCAPE
+ | EXCEPT | EXCEPTION
+ | EXEC | EXECUTE | EXISTS
+ | EXTERNAL | EXTRACT
+ | FALSE | FETCH | FIRST | FLOAT | FOR
+ | FOREIGN | FOUND | FROM | FULL
+ | GET | GLOBAL | GO | GOTO
+ | GRANT | GROUP
+ | HAVING | HOUR
+ | IDENTITY | IMMEDIATE | IN | INDICATOR
+ | INITIALLY | INNER | INPUT
+ | INSENSITIVE | INSERT | INT | INTEGER | INTERSECT
+ | INTERVAL | INTO | IS
+ | ISOLATION
+ | JOIN
+ | KEY
+ | LANGUAGE | LAST | LEADING | LEFT
+ | LEVEL | LIKE | LOCAL | LOWER
+ | MATCH | MAX | MIN | MINUTE | MODULE
+ | MONTH
+ | NAMES | NATIONAL | NATURAL | NCHAR | NEXT | NO
+ | NOT | NULL
+ | NULLIF | NUMERIC
+ | OCTET_LENGTH | OF
+ | ON | ONLY | OPEN | OPTION | OR
+ | ORDER | OUTER
+ | OUTPUT | OVERLAPS
+ | PAD | PARTIAL | POSITION | PRECISION | PREPARE
+ | PRESERVE | PRIMARY
+ | PRIOR | PRIVILEGES | PROCEDURE | PUBLIC
+ | READ | REAL | REFERENCES | RELATIVE | RESTRICT
+ | REVOKE | RIGHT
+ | ROLLBACK | ROWS
+ | SCHEMA | SCROLL | SECOND | SECTION
+ | SELECT
+ | SESSION | SESSION_USER | SET
+ | SIZE | SMALLINT | SOME | SPACE | SQL | SQLCODE
+ | SQLERROR | SQLSTATE
+ | SUBSTRING | SUM | SYSTEM_USER
+ | TABLE | TEMPORARY
+ | THEN | TIME | TIMESTAMP
+ | TIMEZONE_HOUR | TIMEZONE_MINUTE
+ | TO | TRAILING | TRANSACTION
+ | TRANSLATE | TRANSLATION | TRIM | TRUE
+ | UNION | UNIQUE | UNKNOWN | UPDATE | UPPER | USAGE
+ | USER | USING
+ | VALUE | VALUES | VARCHAR | VARYING | VIEW
+ | WHEN | WHENEVER | WHERE | WITH | WORK | WRITE
+ | YEAR
+ | ZONE
+
+<non-reserved word> ::=
+
+ ADA
+ | C | CATALOG_NAME
+ | CHARACTER_SET_CATALOG | CHARACTER_SET_NAME
+ | CHARACTER_SET_SCHEMA | CLASS_ORIGIN | COBOL | COLLATION_CATALOG
+ | COLLATION_NAME | COLLATION_SCHEMA | COLUMN_NAME | COMMAND_FUNCTION
+ | COMMITTED
+ | CONDITION_NUMBER | CONNECTION_NAME | CONSTRAINT_CATALOG | CONSTRAINT_NAME
+ | CONSTRAINT_SCHEMA | CURSOR_NAME
+ | DATA | DATETIME_INTERVAL_CODE
+ | DATETIME_INTERVAL_PRECISION | DYNAMIC_FUNCTION
+ | FORTRAN
+ | LENGTH
+ | MESSAGE_LENGTH | MESSAGE_OCTET_LENGTH | MESSAGE_TEXT | MORE | MUMPS
+ | NAME | NULLABLE | NUMBER
+ | PASCAL | PLI
+ | REPEATABLE | RETURNED_LENGTH | RETURNED_OCTET_LENGTH | RETURNED_SQLSTATE
+ | ROW_COUNT
+ | SCALE | SCHEMA_NAME | SERIALIZABLE | SERVER_NAME | SUBCLASS_ORIGIN
+ | TABLE_NAME | TYPE
+ | UNCOMMITTED | UNNAMED
+
+<unsigned numeric literal> ::=
+ <exact numeric literal>
+ | <approximate numeric literal>
+
+<exact numeric literal> ::=
+ <unsigned integer> [ <period> [ <unsigned integer> ] ]
+ | <period> <unsigned integer>
+
+<unsigned integer> ::= <digit>...
+
+<approximate numeric literal> ::= <mantissa> E <exponent>
+
+<mantissa> ::= <exact numeric literal>
+
+<exponent> ::= <signed integer>
+
+<signed integer> ::= [ <sign> ] <unsigned integer>
+
+<sign> ::= <plus sign> | <minus sign>
+
+<national character string literal> ::=
+ N <quote> [ <character representation>... ] <quote>
+ [ { <separator>... <quote> [ <character representation>... ] <quote> }... ]
+
+<character representation> ::=
+ <nonquote character>
+ | <quote symbol>
+
+<nonquote character> ::= !! <EMPHASIS>(See the Syntax Rules.)
+
+<quote symbol> ::= <quote><quote>
+
+<separator> ::= { <comment> | <space> | <newline> }...
+
+<comment> ::=
+ <comment introducer> [ <comment character>... ] <newline>
+
+<comment introducer> ::= <minus sign><minus sign>[<minus sign>...]
+
+<comment character> ::=
+ <nonquote character>
+ | <quote>
+
+<newline> ::= !! <EMPHASIS>(implementation-defined end-of-line indicator)
+
+<bit string literal> ::=
+ B <quote> [ <bit>... ] <quote>
+ [ { <separator>... <quote> [ <bit>... ] <quote> }... ]
+
+<bit> ::= 0 | 1
+
+<hex string literal> ::=
+ X <quote> [ <hexit>... ] <quote>
+ [ { <separator>... <quote> [ <hexit>... ] <quote> }... ]
+
+<hexit> ::= <digit> | A | B | C | D | E | F | a | b | c | d | e | f
+
+<delimiter token> ::=
+ <character string literal>
+ | <date string>
+ | <time string>
+ | <timestamp string>
+ | <interval string>
+ | <delimited identifier>
+ | <SQL special character>
+ | <not equals operator>
+ | <greater than or equals operator>
+ | <less than or equals operator>
+ | <concatenation operator>
+ | <double period>
+ | <left bracket>
+ | <right bracket>
+
+<character string literal> ::=
+ [ <introducer><character set specification> ]
+ <quote> [ <character representation>... ] <quote>
+ [ { <separator>... <quote> [ <character representation>... ] <quote> }... ]
+
+<introducer> ::= <underscore>
+
+<character set specification> ::=
+ <standard character repertoire name>
+ | <implementation-defined character repertoire name>
+ | <user-defined character repertoire name>
+ | <standard universal character form-of-use name>
+ | <implementation-defined universal character form-of-use name>
+
+<standard character repertoire name> ::= <character set name>
+
+<character set name> ::= [ <schema name> <period> ]
+ <SQL language identifier>
+
+<schema name> ::=
+ [ <catalog name> <period> ] <unqualified schema name>
+
+<catalog name> ::= <identifier>
+
+<identifier> ::=
+ [ <introducer><character set specification> ] <actual identifier>
+
+<actual identifier> ::=
+ <regular identifier>
+ | <delimited identifier>
+
+<delimited identifier> ::=
+ <double quote> <delimited identifier body> <double quote>
+
+<delimited identifier body> ::= <delimited identifier part>...
+
+<delimited identifier part> ::=
+ <nondoublequote character>
+ | <doublequote symbol>
+
+<nondoublequote character> ::= <EMPHASIS>(!! See the Syntax Rules)
+
+<doublequote symbol> ::= <double quote><double quote>
+
+<unqualified schema name> ::= <identifier>
+
+<SQL language identifier> ::=
+ <SQL language identifier start>
+ [ { <underscore> | <SQL language identifier part> }... ]
+
+<SQL language identifier start> ::= <simple Latin letter>
+
+<SQL language identifier part> ::=
+ <simple Latin letter>
+ | <digit>
+
+<implementation-defined character repertoire name> ::=
+ <character set name>
+
+<user-defined character repertoire name> ::= <character set name>
+
+<standard universal character form-of-use name> ::=
+ <character set name>
+
+<implementation-defined universal character form-of-use name> ::=
+ <character set name>
+
+<date string> ::=
+ <quote> <date value> <quote>
+
+<date value> ::=
+ <years value> <minus sign> <months value>
+ <minus sign> <days value>
+
+<years value> ::= <datetime value>
+
+<datetime value> ::= <unsigned integer>
+
+<months value> ::= <datetime value>
+
+<days value> ::= <datetime value>
+
+<time string> ::=
+ <quote> <time value> [ <time zone interval> ] <quote>
+
+<time value> ::=
+ <hours value> <colon> <minutes value> <colon> <seconds value>
+
+<hours value> ::= <datetime value>
+
+<minutes value> ::= <datetime value>
+
+<seconds value> ::=
+ <seconds integer value> [ <period> [ <seconds fraction> ] ]
+
+<seconds integer value> ::= <unsigned integer>
+
+<seconds fraction> ::= <unsigned integer>
+
+<time zone interval> ::=
+ <sign> <hours value> <colon> <minutes value>
+
+<timestamp string> ::=
+ <quote> <date value> <space> <time value>
+ [ <time zone interval> ] <quote>
+
+<interval string> ::=
+ <quote> { <year-month literal> | <day-time literal> } <quote>
+
+<year-month literal> ::=
+ <years value>
+ | [ <years value> <minus sign> ] <months value>
+
+<day-time literal> ::=
+ <day-time interval>
+ | <time interval>
+
+<day-time interval> ::=
+ <days value>
+ [ <space> <hours value> [ <colon> <minutes value>
+ [ <colon> <seconds value> ] ] ]
+
+<time interval> ::=
+ <hours value> [ <colon> <minutes value> [ <colon> <seconds value> ] ]
+ | <minutes value> [ <colon> <seconds value> ]
+ | <seconds value>
+
+<not equals operator> ::= <>
+
+<greater than or equals operator> ::= >=
+
+<less than or equals operator> ::= <=
+
+<concatenation operator> ::= ||
+
+<double period> ::= ..
+
+<module> ::=
+ <module name clause>
+ <language clause>
+ <module authorization clause>
+ [ <temporary table declaration>... ]
+ <module contents>...
+
+<module name clause> ::=
+ MODULE [ <module name> ]
+ [ <module character set specification> ]
+
+<module name> ::= <identifier>
+
+<module character set specification> ::=
+ NAMES ARE <character set specification>
+
+<language clause> ::=
+ LANGUAGE <language name>
+
+<language name> ::=
+ ADA | C | COBOL | FORTRAN | MUMPS | PASCAL | PLI
+
+<module authorization clause> ::=
+ SCHEMA <schema name>
+ | AUTHORIZATION <module authorization identifier>
+ | SCHEMA <schema name>
+ AUTHORIZATION <module authorization identifier>
+
+<module authorization identifier> ::=
+ <authorization identifier>
+
+<authorization identifier> ::= <identifier>
+
+<temporary table declaration> ::=
+ DECLARE LOCAL TEMPORARY TABLE
+ <qualified local table name>
+ <table element list>
+ [ ON COMMIT { PRESERVE | DELETE } ROWS ]
+
+<qualified local table name> ::=
+ MODULE <period> <local table name>
+
+<local table name> ::= <qualified identifier>
+
+<qualified identifier> ::= <identifier>
+
+<table element list> ::=
+ <left paren> <table element> [ { <comma> <table element> }... ] <right paren>
+
+<table element> ::=
+ <column definition>
+ | <table constraint definition>
+
+<column definition> ::=
+ <column name> { <data type> | <domain name> }
+ [ <default clause> ]
+ [ <column constraint definition>... ]
+ [ <collate clause> ]
+
+<column name> ::= <identifier>
+
+<data type> ::=
+ <character string type>
+ [ CHARACTER SET <character set specification> ]
+ | <national character string type>
+ | <bit string type>
+ | <numeric type>
+ | <datetime type>
+ | <interval type>
+
+<character string type> ::=
+ CHARACTER [ <left paren> <length> <right paren> ]
+ | CHAR [ <left paren> <length> <right paren> ]
+ | CHARACTER VARYING <left paren> <length> <right paren>
+ | CHAR VARYING <left paren> <length> <right paren>
+ | VARCHAR <left paren> <length> <right paren>
+
+<length> ::= <unsigned integer>
+
+<national character string type> ::=
+ NATIONAL CHARACTER [ <left paren> <length> <right paren> ]
+ | NATIONAL CHAR [ <left paren> <length> <right paren> ]
+ | NCHAR [ <left paren> <length> <right paren> ]
+ | NATIONAL CHARACTER VARYING <left paren> <length> <right paren>
+ | NATIONAL CHAR VARYING <left paren> <length> <right paren>
+ | NCHAR VARYING <left paren> <length> <right paren>
+
+<bit string type> ::=
+ BIT [ <left paren> <length> <right paren> ]
+ | BIT VARYING <left paren> <length> <right paren>
+
+<numeric type> ::=
+ <exact numeric type>
+ | <approximate numeric type>
+
+<exact numeric type> ::=
+ NUMERIC [ <left paren> <precision> [ <comma> <scale> ] <right paren> ]
+ | DECIMAL [ <left paren> <precision> [ <comma> <scale> ] <right paren> ]
+ | DEC [ <left paren> <precision> [ <comma> <scale> ] <right paren> ]
+ | INTEGER
+ | INT
+ | SMALLINT
+
+<precision> ::= <unsigned integer>
+
+<scale> ::= <unsigned integer>
+
+<approximate numeric type> ::=
+ FLOAT [ <left paren> <precision> <right paren> ]
+ | REAL
+ | DOUBLE PRECISION
+
+<datetime type> ::=
+ DATE
+ | TIME [ <left paren> <time precision> <right paren> ]
+ [ WITH TIME ZONE ]
+ | TIMESTAMP [ <left paren> <timestamp precision> <right paren> ]
+ [ WITH TIME ZONE ]
+
+<time precision> ::= <time fractional seconds precision>
+
+<time fractional seconds precision> ::= <unsigned integer>
+
+<timestamp precision> ::= <time fractional seconds precision>
+
+<interval type> ::= INTERVAL <interval qualifier>
+
+<interval qualifier> ::=
+ <start field> TO <end field>
+ | <single datetime field>
+
+<start field> ::=
+ <non-second datetime field>
+ [ <left paren> <interval leading field precision> <right paren> ]
+
+<non-second datetime field> ::= YEAR | MONTH | DAY | HOUR
+ | MINUTE
+
+<interval leading field precision> ::= <unsigned integer>
+
+<end field> ::=
+ <non-second datetime field>
+ | SECOND [ <left paren> <interval fractional seconds precision> <right paren> ]
+
+<interval fractional seconds precision> ::= <unsigned integer>
+
+<single datetime field> ::=
+ <non-second datetime field>
+ [ <left paren> <interval leading field precision> <right paren> ]
+ | SECOND [ <left paren> <interval leading field precision>
+ [ <comma> <interval fractional seconds precision> ] <right paren> ]
+
+<domain name> ::= <qualified name>
+
+<qualified name> ::=
+ [ <schema name> <period> ] <qualified identifier>
+
+<default clause> ::=
+ DEFAULT <default option>
+
+<default option> ::=
+ <literal>
+ | <datetime value function>
+ | USER
+ | CURRENT_USER
+ | SESSION_USER
+ | SYSTEM_USER
+ | NULL
+
+<literal> ::=
+ <signed numeric literal>
+ | <general literal>
+
+<signed numeric literal> ::=
+ [ <sign> ] <unsigned numeric literal>
+
+<general literal> ::=
+ <character string literal>
+ | <national character string literal>
+ | <bit string literal>
+ | <hex string literal>
+ | <datetime literal>
+ | <interval literal>
+
+<datetime literal> ::=
+ <date literal>
+ | <time literal>
+ | <timestamp literal>
+
+<date literal> ::=
+ DATE <date string>
+
+<time literal> ::=
+ TIME <time string>
+
+<timestamp literal> ::=
+ TIMESTAMP <timestamp string>
+
+<interval literal> ::=
+ INTERVAL [ <sign> ] <interval string> <interval qualifier>
+
+<datetime value function> ::=
+ <current date value function>
+ | <current time value function>
+ | <current timestamp value function>
+
+<current date value function> ::= CURRENT_DATE
+
+<current time value function> ::=
+ CURRENT_TIME [ <left paren> <time precision> <right paren> ]
+
+<current timestamp value function> ::=
+ CURRENT_TIMESTAMP [ <left paren> <timestamp precision> <right paren> ]
+
+<column constraint definition> ::=
+ [ <constraint name definition> ]
+ <column constraint>
+ [ <constraint attributes> ]
+
+<constraint name definition> ::= CONSTRAINT <constraint name>
+
+<constraint name> ::= <qualified name>
+
+<column constraint> ::=
+ NOT NULL
+ | <unique specification>
+ | <references specification>
+ | <check constraint definition>
+
+<unique specification> ::=
+ UNIQUE | PRIMARY KEY
+
+<references specification> ::=
+ REFERENCES <referenced table and columns>
+ [ MATCH <match type> ]
+ [ <referential triggered action> ]
+
+<referenced table and columns> ::=
+ <table name> [ <left paren> <reference column list> <right paren> ]
+
+<table name> ::=
+ <qualified name>
+ | <qualified local table name>
+
+<reference column list> ::= <column name list>
+
+<column name list> ::=
+ <column name> [ { <comma> <column name> }... ]
+
+<match type> ::=
+ FULL
+ | PARTIAL
+
+<referential triggered action> ::=
+ <update rule> [ <delete rule> ]
+ | <delete rule> [ <update rule> ]
+
+<update rule> ::= ON UPDATE <referential action>
+
+<referential action> ::=
+ CASCADE
+ | SET NULL
+ | SET DEFAULT
+ | NO ACTION
+
+<delete rule> ::= ON DELETE <referential action>
+
+<check constraint definition> ::=
+ CHECK
+ <left paren> <search condition> <right paren>
+
+<search condition> ::=
+ <boolean term>
+ | <search condition> OR <boolean term>
+
+<boolean term> ::=
+ <boolean factor>
+ | <boolean term> AND <boolean factor>
+
+<boolean factor> ::=
+ [ NOT ] <boolean test>
+
+<boolean test> ::=
+ <boolean primary> [ IS [ NOT ]
+ <truth value> ]
+
+<boolean primary> ::=
+ <predicate>
+ | <left paren> <search condition> <right paren>
+
+<predicate> ::=
+ <comparison predicate>
+ | <between predicate>
+ | <in predicate>
+ | <like predicate>
+ | <null predicate>
+ | <quantified comparison predicate>
+ | <exists predicate>
+ | <unique predicate>
+ | <match predicate>
+ | <overlaps predicate>
+
+<comparison predicate> ::=
+ <row value constructor> <comp op>
+ <row value constructor>
+
+<row value constructor> ::=
+ <row value constructor element>
+ | <left paren> <row value constructor list> <right paren>
+ | <row subquery>
+
+<row value constructor element> ::=
+ <value expression>
+ | <null specification>
+ | <default specification>
+
+<value expression> ::=
+ <numeric value expression>
+ | <string value expression>
+ | <datetime value expression>
+ | <interval value expression>
+
+<numeric value expression> ::=
+ <term>
+ | <numeric value expression> <plus sign> <term>
+ | <numeric value expression> <minus sign> <term>
+
+<term> ::=
+ <factor>
+ | <term> <asterisk> <factor>
+ | <term> <solidus> <factor>
+
+<factor> ::=
+ [ <sign> ] <numeric primary>
+
+<numeric primary> ::=
+ <value expression primary>
+ | <numeric value function>
+
+<value expression primary> ::=
+ <unsigned value specification>
+ | <column reference>
+ | <set function specification>
+ | <scalar subquery>
+ | <case expression>
+ | <left paren> <value expression> <right paren>
+ | <cast specification>
+
+<unsigned value specification> ::=
+ <unsigned literal>
+ | <general value specification>
+
+<unsigned literal> ::=
+ <unsigned numeric literal>
+ | <general literal>
+
+<general value specification> ::=
+ <parameter specification>
+ | <dynamic parameter specification>
+ | <variable specification>
+ | USER
+ | CURRENT_USER
+ | SESSION_USER
+ | SYSTEM_USER
+ | VALUE
+
+<parameter specification> ::=
+ <parameter name> [ <indicator parameter> ]
+
+<parameter name> ::= <colon> <identifier>
+
+<indicator parameter> ::=
+ [ INDICATOR ] <parameter name>
+
+<dynamic parameter specification> ::= <question mark>
+
+<variable specification> ::=
+ <embedded variable name> [ <indicator variable> ]
+
+<embedded variable name> ::=
+ <colon><host identifier>
+
+<host identifier> ::=
+ <Ada host identifier>
+ | <C host identifier>
+ | <COBOL host identifier>
+ | <Fortran host identifier>
+ | <MUMPS host identifier>
+ | <Pascal host identifier>
+ | <PL/I host identifier>
+
+<Ada host identifier> ::= !! <EMPHASIS>(See the Syntax Rules.)
+
+<C host identifier> ::=
+ !! <EMPHASIS>(See the Syntax Rules.)
+
+<COBOL host identifier> ::= !! <EMPHASIS>(See the Syntax Rules.)
+
+<Fortran host identifier> ::= !! <EMPHASIS>(See the Syntax Rules.)
+
+<MUMPS host identifier> ::= !! <EMPHASIS>(See the Syntax Rules.)
+
+<Pascal host identifier> ::= !! <EMPHASIS>(See the Syntax Rules.)
+
+<PL/I host identifier> ::= !! <EMPHASIS>(See the Syntax Rules.)
+
+<indicator variable> ::=
+ [ INDICATOR ] <embedded variable name>
+
+<column reference> ::= [ <qualifier> <period> ] <column name>
+
+<qualifier> ::=
+ <table name>
+ | <correlation name>
+
+<correlation name> ::= <identifier>
+
+<set function specification> ::=
+ COUNT <left paren> <asterisk> <right paren>
+ | <general set function>
+
+<general set function> ::=
+ <set function type>
+ <left paren> [ <set quantifier> ] <value expression> <right paren>
+
+<set function type> ::=
+ AVG | MAX | MIN | SUM | COUNT
+
+<set quantifier> ::= DISTINCT | ALL
+
+<scalar subquery> ::= <subquery>
+
+<subquery> ::= <left paren> <query expression> <right paren>
+
+<query expression> ::=
+ <non-join query expression>
+ | <joined table>
+
+<non-join query expression> ::=
+ <non-join query term>
+ | <query expression> UNION [ ALL ]
+ [ <corresponding spec> ] <query term>
+ | <query expression> EXCEPT [ ALL ]
+ [ <corresponding spec> ] <query term>
+
+<non-join query term> ::=
+ <non-join query primary>
+ | <query term> INTERSECT [ ALL ]
+ [ <corresponding spec> ] <query primary>
+
+<non-join query primary> ::=
+ <simple table>
+ | <left paren> <non-join query expression> <right paren>
+
+<simple table> ::=
+ <query specification>
+ | <table value constructor>
+ | <explicit table>
+
+<query specification> ::=
+ SELECT [ <set quantifier> ] <select list> <table expression>
+
+<select list> ::=
+ <asterisk>
+ | <select sublist> [ { <comma> <select sublist> }... ]
+
+<select sublist> ::=
+ <derived column>
+ | <qualifier> <period> <asterisk>
+
+<derived column> ::= <value expression> [ <as clause> ]
+
+<as clause> ::= [ AS ] <column name>
+
+<table expression> ::=
+ <from clause>
+ [ <where clause> ]
+ [ <group by clause> ]
+ [ <having clause> ]
+
+<from clause> ::= FROM <table reference>
+ [ { <comma> <table reference> }... ]
+
+<table reference> ::=
+ <table name> [ [ AS ] <correlation name>
+ [ <left paren> <derived column list> <right paren> ] ]
+ | <derived table> [ AS ] <correlation name>
+ [ <left paren> <derived column list> <right paren> ]
+ | <joined table>
+
+<derived column list> ::= <column name list>
+
+<derived table> ::= <table subquery>
+
+<table subquery> ::= <subquery>
+
+<joined table> ::=
+ <cross join>
+ | <qualified join>
+ | <left paren> <joined table> <right paren>
+
+<cross join> ::=
+ <table reference> CROSS JOIN <table reference>
+
+<qualified join> ::=
+ <table reference> [ NATURAL ] [ <join type> ] JOIN
+ <table reference> [ <join specification> ]
+
+<join type> ::=
+ INNER
+ | <outer join type> [ OUTER ]
+ | UNION
+
+<outer join type> ::=
+ LEFT
+ | RIGHT
+ | FULL
+
+<join specification> ::=
+ <join condition>
+ | <named columns join>
+
+<join condition> ::= ON <search condition>
+
+<named columns join> ::=
+ USING <left paren> <join column list> <right paren>
+
+<join column list> ::= <column name list>
+
+<where clause> ::= WHERE <search condition>
+
+<group by clause> ::=
+ GROUP BY <grouping column reference list>
+
+<grouping column reference list> ::=
+ <grouping column reference>
+ [ { <comma> <grouping column reference> }... ]
+
+<grouping column reference> ::=
+ <column reference> [ <collate clause> ]
+
+<collate clause> ::= COLLATE <collation name>
+
+<collation name> ::= <qualified name>
+
+<having clause> ::= HAVING <search condition>
+
+<table value constructor> ::=
+ VALUES <table value constructor list>
+
+<table value constructor list> ::=
+ <row value constructor> [ { <comma> <row value constructor> }... ]
+
+<explicit table> ::= TABLE <table name>
+
+<query term> ::=
+ <non-join query term>
+ | <joined table>
+
+<corresponding spec> ::=
+ CORRESPONDING [ BY <left paren> <corresponding column list> <right paren> ]
+
+<corresponding column list> ::= <column name list>
+
+<query primary> ::=
+ <non-join query primary>
+ | <joined table>
+
+<case expression> ::=
+ <case abbreviation>
+ | <case specification>
+
+<case abbreviation> ::=
+ NULLIF <left paren> <value expression> <comma>
+ <value expression> <right paren>
+ | COALESCE <left paren> <value expression>
+ { <comma> <value expression> }... <right paren>
+
+<case specification> ::=
+ <simple case>
+ | <searched case>
+
+<simple case> ::=
+ CASE <case operand>
+ <simple when clause>...
+ [ <else clause> ]
+ END
+
+<case operand> ::= <value expression>
+
+<simple when clause> ::= WHEN <when operand> THEN <result>
+
+<when operand> ::= <value expression>
+
+<result> ::= <result expression> | NULL
+
+<result expression> ::= <value expression>
+
+<else clause> ::= ELSE <result>
+
+<searched case> ::=
+ CASE
+ <searched when clause>...
+ [ <else clause> ]
+ END
+
+<searched when clause> ::= WHEN <search condition> THEN <result>
+
+<cast specification> ::=
+ CAST <left paren> <cast operand> AS
+ <cast target> <right paren>
+
+<cast operand> ::=
+ <value expression>
+ | NULL
+
+<cast target> ::=
+ <domain name>
+ | <data type>
+
+<numeric value function> ::=
+ <position expression>
+ | <extract expression>
+ | <length expression>
+
+<position expression> ::=
+ POSITION <left paren> <character value expression>
+ IN <character value expression> <right paren>
+
+<character value expression> ::=
+ <concatenation>
+ | <character factor>
+
+<concatenation> ::=
+ <character value expression> <concatenation operator>
+ <character factor>
+
+<character factor> ::=
+ <character primary> [ <collate clause> ]
+
+<character primary> ::=
+ <value expression primary>
+ | <string value function>
+
+<string value function> ::=
+ <character value function>
+ | <bit value function>
+
+<character value function> ::=
+ <character substring function>
+ | <fold>
+ | <form-of-use conversion>
+ | <character translation>
+ | <trim function>
+
+<character substring function> ::=
+ SUBSTRING <left paren> <character value expression> FROM <start position>
+ [ FOR <string length> ] <right paren>
+
+<start position> ::= <numeric value expression>
+
+<string length> ::= <numeric value expression>
+
+<fold> ::= { UPPER | LOWER }
+ <left paren> <character value expression> <right paren>
+
+<form-of-use conversion> ::=
+ CONVERT <left paren> <character value expression>
+ USING <form-of-use conversion name> <right paren>
+
+<form-of-use conversion name> ::= <qualified name>
+
+<character translation> ::=
+ TRANSLATE <left paren> <character value expression>
+ USING <translation name> <right paren>
+
+<translation name> ::= <qualified name>
+
+<trim function> ::=
+ TRIM <left paren> <trim operands> <right paren>
+
+<trim operands> ::=
+ [ [ <trim specification> ] [ <trim character> ] FROM ] <trim source>
+
+<trim specification> ::=
+ LEADING
+ | TRAILING
+ | BOTH
+
+<trim character> ::= <character value expression>
+
+<trim source> ::= <character value expression>
+
+<bit value function> ::=
+ <bit substring function>
+
+<bit substring function> ::=
+ SUBSTRING <left paren> <bit value expression> FROM <start position>
+ [ FOR <string length> ] <right paren>
+
+<bit value expression> ::=
+ <bit concatenation>
+ | <bit factor>
+
+<bit concatenation> ::=
+ <bit value expression> <concatenation operator> <bit factor>
+
+<bit factor> ::= <bit primary>
+
+<bit primary> ::=
+ <value expression primary>
+ | <string value function>
+
+<extract expression> ::=
+ EXTRACT <left paren> <extract field>
+ FROM <extract source> <right paren>
+
+<extract field> ::=
+ <datetime field>
+ | <time zone field>
+
+<datetime field> ::=
+ <non-second datetime field>
+ | SECOND
+
+<time zone field> ::=
+ TIMEZONE_HOUR
+ | TIMEZONE_MINUTE
+
+<extract source> ::=
+ <datetime value expression>
+ | <interval value expression>
+
+<datetime value expression> ::=
+ <datetime term>
+ | <interval value expression> <plus sign> <datetime term>
+ | <datetime value expression> <plus sign> <interval term>
+ | <datetime value expression> <minus sign> <interval term>
+
+<interval term> ::=
+ <interval factor>
+ | <interval term 2> <asterisk> <factor>
+ | <interval term 2> <solidus> <factor>
+ | <term> <asterisk> <interval factor>
+
+<interval factor> ::=
+ [ <sign> ] <interval primary>
+
+<interval primary> ::=
+ <value expression primary> [ <interval qualifier> ]
+
+<interval term 2> ::= <interval term>
+
+<interval value expression> ::=
+ <interval term>
+ | <interval value expression 1> <plus sign> <interval term 1>
+ | <interval value expression 1> <minus sign> <interval term 1>
+ | <left paren> <datetime value expression> <minus sign>
+ <datetime term> <right paren> <interval qualifier>
+
+<interval value expression 1> ::= <interval value expression>
+
+<interval term 1> ::= <interval term>
+
+<datetime term> ::=
+ <datetime factor>
+
+<datetime factor> ::=
+ <datetime primary> [ <time zone> ]
+
+<datetime primary> ::=
+ <value expression primary>
+ | <datetime value function>
+
+<time zone> ::=
+ AT <time zone specifier>
+
+<time zone specifier> ::=
+ LOCAL
+ | TIME ZONE <interval value expression>
+
+<length expression> ::=
+ <char length expression>
+ | <octet length expression>
+ | <bit length expression>
+
+<char length expression> ::=
+ { CHAR_LENGTH | CHARACTER_LENGTH }
+ <left paren> <string value expression> <right paren>
+
+<string value expression> ::=
+ <character value expression>
+ | <bit value expression>
+
+<octet length expression> ::=
+ OCTET_LENGTH <left paren> <string value expression> <right paren>
+
+<bit length expression> ::=
+ BIT_LENGTH <left paren> <string value expression> <right paren>
+
+<null specification> ::=
+ NULL
+
+<default specification> ::=
+ DEFAULT
+
+<row value constructor list> ::=
+ <row value constructor element>
+ [ { <comma> <row value constructor element> }... ]
+
+<row subquery> ::= <subquery>
+
+<comp op> ::=
+ <equals operator>
+ | <not equals operator>
+ | <less than operator>
+ | <greater than operator>
+ | <less than or equals operator>
+ | <greater than or equals operator>
+
+<between predicate> ::=
+ <row value constructor> [ NOT ] BETWEEN
+ <row value constructor> AND <row value constructor>
+
+<in predicate> ::=
+ <row value constructor>
+ [ NOT ] IN <in predicate value>
+
+<in predicate value> ::=
+ <table subquery>
+ | <left paren> <in value list> <right paren>
+
+<in value list> ::=
+ <value expression> { <comma> <value expression> }...
+
+<like predicate> ::=
+ <match value> [ NOT ] LIKE <pattern>
+ [ ESCAPE <escape character> ]
+
+<match value> ::= <character value expression>
+
+<pattern> ::= <character value expression>
+
+<escape character> ::= <character value expression>
+
+<null predicate> ::= <row value constructor>
+ IS [ NOT ] NULL
+
+<quantified comparison predicate> ::=
+ <row value constructor> <comp op> <quantifier> <table subquery>
+
+<quantifier> ::= <all> | <some>
+
+<all> ::= ALL
+
+<some> ::= SOME | ANY
+
+<exists predicate> ::= EXISTS <table subquery>
+
+<unique predicate> ::= UNIQUE <table subquery>
+
+<match predicate> ::=
+ <row value constructor> MATCH [ UNIQUE ]
+ [ PARTIAL | FULL ] <table subquery>
+
+<overlaps predicate> ::=
+ <row value constructor 1> OVERLAPS <row value constructor 2>
+
+<row value constructor 1> ::= <row value constructor>
+
+<row value constructor 2> ::= <row value constructor>
+
+<truth value> ::=
+ TRUE
+ | FALSE
+ | UNKNOWN
+
+<constraint attributes> ::=
+ <constraint check time> [ [ NOT ] DEFERRABLE ]
+ | [ NOT ] DEFERRABLE [ <constraint check time> ]
+
+<constraint check time> ::=
+ INITIALLY DEFERRED
+ | INITIALLY IMMEDIATE
+
+<table constraint definition> ::=
+ [ <constraint name definition> ]
+ <table constraint> [ <constraint attributes> ]
+
+<table constraint> ::=
+ <unique constraint definition>
+ | <referential constraint definition>
+ | <check constraint definition>
+
+<unique constraint definition> ::=
+ <unique specification> even in SQL3)
+ <unique specification>
+ <left paren> <unique column list> <right paren>
+
+<unique column list> ::= <column name list>
+
+<referential constraint definition> ::=
+ FOREIGN KEY
+ <left paren> <referencing columns> <right paren>
+ <references specification>
+
+<referencing columns> ::=
+ <reference column list>
+
+<module contents> ::=
+ <declare cursor>
+ | <dynamic declare cursor>
+ | <procedure>
+
+<declare cursor> ::=
+ DECLARE <cursor name> [ INSENSITIVE ] [ SCROLL ] CURSOR
+ FOR <cursor specification>
+
+<cursor name> ::= <identifier>
+
+<cursor specification> ::=
+ <query expression> [ <order by clause> ]
+ [ <updatability clause> ]
+
+<order by clause> ::=
+ ORDER BY <sort specification list>
+
+<sort specification list> ::=
+ <sort specification> [ { <comma> <sort specification> }... ]
+
+<sort specification> ::=
+ <sort key> [ <collate clause> ] [ <ordering specification> ]
+
+<sort key> ::=
+ <column name>
+ | <unsigned integer>
+
+<ordering specification> ::= ASC | DESC
+
+<updatability clause> ::=
+ FOR
+ { READ ONLY |
+ UPDATE [ OF <column name list> ] }
+
+<dynamic declare cursor> ::=
+ DECLARE <cursor name> [ INSENSITIVE ] [ SCROLL ] CURSOR
+ FOR <statement name>
+
+<statement name> ::= <identifier>
+
+<procedure> ::=
+ PROCEDURE <procedure name>
+ <parameter declaration list> <semicolon>
+ <SQL procedure statement> <semicolon>
+
+<procedure name> ::= <identifier>
+
+<parameter declaration list> ::=
+ <left paren> <parameter declaration>
+ [ { <comma> <parameter declaration> }... ] <right paren>
+ | <parameter declaration>...
+
+<parameter declaration> ::=
+ <parameter name> <data type>
+ | <status parameter>
+
+<status parameter> ::=
+ SQLCODE | SQLSTATE
+
+<SQL procedure statement> ::=
+ <SQL schema statement>
+ | <SQL data statement>
+ | <SQL transaction statement>
+ | <SQL connection statement>
+ | <SQL session statement>
+ | <SQL dynamic statement>
+ | <SQL diagnostics statement>
+
+<SQL schema statement> ::=
+ <SQL schema definition statement>
+ | <SQL schema manipulation statement>
+
+<SQL schema definition statement> ::=
+ <schema definition>
+ | <table definition>
+ | <view definition>
+ | <grant statement>
+ | <domain definition>
+ | <character set definition>
+ | <collation definition>
+ | <translation definition>
+ | <assertion definition>
+
+<schema definition> ::=
+ CREATE SCHEMA <schema name clause>
+ [ <schema character set specification> ]
+ [ <schema element>... ]
+
+<schema name clause> ::=
+ <schema name>
+ | AUTHORIZATION <schema authorization identifier>
+ | <schema name> AUTHORIZATION
+ <schema authorization identifier>
+
+<schema authorization identifier> ::=
+ <authorization identifier>
+
+<schema character set specification> ::=
+ DEFAULT CHARACTER
+ SET <character set specification>
+
+<schema element> ::=
+ <domain definition>
+ | <table definition>
+ | <view definition>
+ | <grant statement>
+ | <assertion definition>
+ | <character set definition>
+ | <collation definition>
+ | <translation definition>
+
+<domain definition> ::=
+ CREATE DOMAIN <domain name>
+ [ AS ] <data type>
+ [ <default clause> ]
+ [ <domain constraint>... ]
+ [ <collate clause> ]
+
+<domain constraint> ::=
+ [ <constraint name definition> ]
+ <check constraint definition> [ <constraint attributes> ]
+
+<table definition> ::=
+ CREATE [ { GLOBAL | LOCAL } TEMPORARY ] TABLE
+ <table name>
+ <table element list>
+ [ ON COMMIT { DELETE | PRESERVE } ROWS ]
+
+<view definition> ::=
+ CREATE VIEW <table name> [ <left paren> <view column list>
+ <right paren> ]
+ AS <query expression>
+ [ WITH [ <levels clause> ] CHECK OPTION ]
+
+<view column list> ::= <column name list>
+
+<levels clause> ::=
+ CASCADED | LOCAL
+
+<grant statement> ::=
+ GRANT <privileges> ON <object name>
+ TO <grantee> [ { <comma> <grantee> }... ]
+ [ WITH GRANT OPTION ]
+
+<privileges> ::=
+ ALL PRIVILEGES
+ | <action list>
+
+<action list> ::= <action> [ { <comma> <action> }... ]
+
+<action> ::=
+ SELECT
+ | DELETE
+ | INSERT [ <left paren> <privilege column list> <right paren> ]
+ | UPDATE [ <left paren> <privilege column list> <right paren> ]
+ | REFERENCES [ <left paren> <privilege column list> <right paren> ]
+ | USAGE
+
+<privilege column list> ::= <column name list>
+
+<object name> ::=
+ [ TABLE ] <table name>
+ | DOMAIN <domain name>
+ | COLLATION <collation name>
+ | CHARACTER SET <character set name>
+ | TRANSLATION <translation name>
+
+<grantee> ::=
+ PUBLIC
+ | <authorization identifier>
+
+<assertion definition> ::=
+ CREATE ASSERTION <constraint name> <assertion check>
+ [ <constraint attributes> ]
+
+<assertion check> ::=
+ CHECK
+ <left paren> <search condition> <right paren>
+
+<character set definition> ::=
+ CREATE CHARACTER SET <character set name>
+ [ AS ]
+ <character set source>
+ [ <collate clause> | <limited collation definition> ]
+
+<character set source> ::=
+ GET <existing character set name>
+
+<existing character set name> ::=
+ <standard character repertoire name>
+ | <implementation-defined character repertoire name>
+ | <schema character set name>
+
+<schema character set name> ::= <character set name>
+
+<limited collation definition> ::=
+ COLLATION FROM <collation source>
+
+<collation source> ::=
+ <collating sequence definition>
+ | <translation collation>
+
+<collating sequence definition> ::=
+ <external collation>
+ | <schema collation name>
+ | DESC <left paren> <collation name> <right paren>
+ | DEFAULT
+
+<external collation> ::=
+ EXTERNAL <left paren> <quote> <external collation name> <quote> <right paren>
+
+<external collation name> ::=
+ <standard collation name>
+ | <implementation-defined collation name>
+
+<standard collation name> ::= <collation name>
+
+<implementation-defined collation name> ::= <collation name>
+
+<schema collation name> ::= <collation name>
+
+<translation collation> ::=
+ TRANSLATION <translation name>
+ [ THEN COLLATION <collation name> ]
+
+<collation definition> ::=
+ CREATE COLLATION <collation name> FOR
+ <character set specification>
+ FROM <collation source>
+ [ <pad attribute> ]
+
+<pad attribute> ::=
+ NO PAD
+ | PAD SPACE
+
+<translation definition> ::=
+ CREATE TRANSLATION <translation name>
+ FOR <source character set specification>
+ TO <target character set specification>
+ FROM <translation source>
+
+<source character set specification> ::= <character set specification>
+
+<target character set specification> ::= <character set specification>
+
+<translation source> ::=
+ <translation specification>
+
+<translation specification> ::=
+ <external translation>
+ | IDENTITY
+ | <schema translation name>
+
+<external translation> ::=
+ EXTERNAL <left paren> <quote> <external translation name> <quote> <right paren>
+
+<external translation name> ::=
+ <standard translation name>
+ | <implementation-defined translation name>
+
+<standard translation name> ::= <translation name>
+
+<implementation-defined translation name> ::= <translation name>
+
+<schema translation name> ::= <translation name>
+
+<SQL schema manipulation statement> ::=
+ <drop schema statement>
+ | <alter table statement>
+ | <drop table statement>
+ | <drop view statement>
+ | <revoke statement>
+ | <alter domain statement>
+ | <drop domain statement>
+ | <drop character set statement>
+ | <drop collation statement>
+ | <drop translation statement>
+ | <drop assertion statement>
+
+<drop schema statement> ::=
+ DROP SCHEMA <schema name> <drop behavior>
+
+<drop behavior> ::= CASCADE | RESTRICT
+
+<alter table statement> ::=
+ ALTER TABLE <table name> <alter table action>
+
+<alter table action> ::=
+ <add column definition>
+ | <alter column definition>
+ | <drop column definition>
+ | <add table constraint definition>
+ | <drop table constraint definition>
+
+<add column definition> ::=
+ ADD [ COLUMN ] <column definition>
+
+<alter column definition> ::=
+ ALTER [ COLUMN ] <column name> <alter column action>
+
+<alter column action> ::=
+ <set column default clause>
+ | <drop column default clause>
+
+<set column default clause> ::=
+ SET <default clause>
+
+<drop column default clause> ::=
+ DROP DEFAULT
+
+<drop column definition> ::=
+ DROP [ COLUMN ] <column name> <drop behavior>
+
+<add table constraint definition> ::=
+ ADD <table constraint definition>
+
+<drop table constraint definition> ::=
+ DROP CONSTRAINT <constraint name> <drop behavior>
+
+<drop table statement> ::=
+ DROP TABLE <table name> <drop behavior>
+
+<drop view statement> ::=
+ DROP VIEW <table name> <drop behavior>
+
+<revoke statement> ::=
+ REVOKE [ GRANT OPTION FOR ]
+ <privileges>
+ ON <object name>
+ FROM <grantee> [ { <comma> <grantee> }... ] <drop behavior>
+
+<alter domain statement> ::=
+ ALTER DOMAIN <domain name> <alter domain action>
+
+<alter domain action> ::=
+ <set domain default clause>
+ | <drop domain default clause>
+ | <add domain constraint definition>
+ | <drop domain constraint definition>
+
+<set domain default clause> ::= SET <default clause>
+
+<drop domain default clause> ::= DROP DEFAULT
+
+<add domain constraint definition> ::=
+ ADD <domain constraint>
+
+<drop domain constraint definition> ::=
+ DROP CONSTRAINT <constraint name>
+
+<drop domain statement> ::=
+ DROP DOMAIN <domain name> <drop behavior>
+
+<drop character set statement> ::=
+ DROP CHARACTER SET <character set name>
+
+<drop collation statement> ::=
+ DROP COLLATION <collation name>
+
+<drop translation statement> ::=
+ DROP TRANSLATION <translation name>
+
+<drop assertion statement> ::=
+ DROP ASSERTION <constraint name>
+
+<SQL data statement> ::=
+ <open statement>
+ | <fetch statement>
+ | <close statement>
+ | <select statement: single row>
+ | <SQL data change statement>
+
+<open statement> ::=
+ OPEN <cursor name>
+
+<fetch statement> ::=
+ FETCH [ [ <fetch orientation> ] FROM ]
+ <cursor name> INTO <fetch target list>
+
+<fetch orientation> ::=
+ NEXT
+ | PRIOR
+ | FIRST
+ | LAST
+ | { ABSOLUTE | RELATIVE } <simple value specification>
+
+<simple value specification> ::=
+ <parameter name>
+ | <embedded variable name>
+ | <literal>
+
+<fetch target list> ::=
+ <target specification> [ { <comma> <target specification> }... ]
+
+<target specification> ::=
+ <parameter specification>
+ | <variable specification>
+
+<close statement> ::=
+ CLOSE <cursor name>
+
+<select statement: single row> ::=
+ SELECT [ <set quantifier> ] <select list>
+ INTO <select target list>
+ <table expression>
+
+<select target list> ::=
+ <target specification> [ { <comma> <target specification> }... ]
+
+<SQL data change statement> ::=
+ <delete statement: positioned>
+ | <delete statement: searched>
+ | <insert statement>
+ | <update statement: positioned>
+ | <update statement: searched>
+
+<delete statement: positioned> ::=
+ DELETE FROM <table name>
+ WHERE CURRENT OF <cursor name>
+
+<delete statement: searched> ::=
+ DELETE FROM <table name>
+ [ WHERE <search condition> ]
+
+<insert statement> ::=
+ INSERT INTO <table name>
+ <insert columns and source>
+
+<insert columns and source> ::=
+ [ <left paren> <insert column list> <right paren> ]
+ <query expression>
+ | DEFAULT VALUES
+
+<insert column list> ::= <column name list>
+
+<update statement: positioned> ::=
+ UPDATE <table name>
+ SET <set clause list>
+ WHERE CURRENT OF <cursor name>
+
+<set clause list> ::=
+ <set clause> [ { <comma> <set clause> }... ]
+
+<set clause> ::=
+ <object column> <equals operator> <update source>
+
+<object column> ::= <column name>
+
+<update source> ::=
+ <value expression>
+ | <null specification>
+ | DEFAULT
+
+<update statement: searched> ::=
+ UPDATE <table name>
+ SET <set clause list>
+ [ WHERE <search condition> ]
+
+<SQL transaction statement> ::=
+ <set transaction statement>
+ | <set constraints mode statement>
+ | <commit statement>
+ | <rollback statement>
+
+<set transaction statement> ::=
+ SET TRANSACTION <transaction mode>
+ [ { <comma> <transaction mode> }... ]
+
+<transaction mode> ::=
+ <isolation level>
+ | <transaction access mode>
+ | <diagnostics size>
+
+<isolation level> ::=
+ ISOLATION LEVEL <level of isolation>
+
+<level of isolation> ::=
+ READ UNCOMMITTED
+ | READ COMMITTED
+ | REPEATABLE READ
+ | SERIALIZABLE
+
+<transaction access mode> ::=
+ READ ONLY
+ | READ WRITE
+
+<diagnostics size> ::=
+ DIAGNOSTICS SIZE <number of conditions>
+
+<number of conditions> ::= <simple value specification>
+
+<set constraints mode statement> ::=
+ SET CONSTRAINTS <constraint name list>
+ { DEFERRED | IMMEDIATE }
+
+<constraint name list> ::=
+ ALL
+ | <constraint name> [ { <comma> <constraint name> }... ]
+
+<commit statement> ::=
+ COMMIT [ WORK ]
+
+<rollback statement> ::=
+ ROLLBACK [ WORK ]
+
+<SQL connection statement> ::=
+ <connect statement>
+ | <set connection statement>
+ | <disconnect statement>
+
+<connect statement> ::=
+ CONNECT TO <connection target>
+
+<connection target> ::=
+ <SQL-server name>
+ [ AS <connection name> ]
+ correspondence with Tony Gordon)
+ [ USER <user name> ]
+ | DEFAULT
+
+<SQL-server name> ::= <simple value specification>
+
+<connection name> ::= <simple value specification>
+
+<user name> ::= <simple value specification>
+
+<set connection statement> ::=
+ SET CONNECTION <connection object>
+
+<connection object> ::=
+ DEFAULT
+ | <connection name>
+
+<disconnect statement> ::=
+ DISCONNECT <disconnect object>
+
+<disconnect object> ::=
+ <connection object>
+ | ALL
+ | CURRENT
+
+<SQL session statement> ::=
+ <set catalog statement>
+ | <set schema statement>
+ | <set names statement>
+ | <set session authorization identifier statement>
+ | <set local time zone statement>
+
+<set catalog statement> ::=
+ SET CATALOG <value specification>
+
+<value specification> ::=
+ <literal>
+ | <general value specification>
+
+<set schema statement> ::=
+ SET SCHEMA <value specification>
+
+<set names statement> ::=
+ SET NAMES <value specification>
+
+<set session authorization identifier statement> ::=
+ SET SESSION AUTHORIZATION
+ <value specification>
+
+<set local time zone statement> ::=
+ SET TIME ZONE
+ <set time zone value>
+
+<set time zone value> ::=
+ <interval value expression>
+ | LOCAL
+
+<SQL dynamic statement> ::=
+ <system descriptor statement>
+ | <prepare statement>
+ | <deallocate prepared statement>
+ | <describe statement>
+ | <execute statement>
+ | <execute immediate statement>
+ | <SQL dynamic data statement>
+
+<system descriptor statement> ::=
+ <allocate descriptor statement>
+ | <deallocate descriptor statement>
+ | <set descriptor statement>
+ | <get descriptor statement>
+
+<allocate descriptor statement> ::=
+ ALLOCATE DESCRIPTOR <descriptor name>
+ [ WITH MAX <occurrences> ]
+
+<descriptor name> ::=
+ [ <scope option> ] <simple value specification>
+
+<scope option> ::=
+ GLOBAL
+ | LOCAL
+
+<occurrences> ::= <simple value specification>
+
+<deallocate descriptor statement> ::=
+ DEALLOCATE DESCRIPTOR <descriptor name>
+
+<set descriptor statement> ::=
+ SET DESCRIPTOR <descriptor name>
+ <set descriptor information>
+
+<set descriptor information> ::=
+ <set count>
+ | VALUE <item number>
+ <set item information> [ { <comma> <set item information> }... ]
+
+<set count> ::=
+ COUNT <equals operator> <simple value specification 1>
+
+<simple value specification 1> ::= <simple value specification>
+
+<item number> ::= <simple value specification>
+
+<set item information> ::=
+ <descriptor item name> <equals operator> <simple value specification 2>
+
+<descriptor item name> ::=
+ TYPE
+ | LENGTH
+ | OCTET_LENGTH
+ | RETURNED_LENGTH
+ | RETURNED_OCTET_LENGTH
+ | PRECISION
+ | SCALE
+ | DATETIME_INTERVAL_CODE
+ | DATETIME_INTERVAL_PRECISION
+ | NULLABLE
+ | INDICATOR
+ | DATA
+ | NAME
+ | UNNAMED
+ | COLLATION_CATALOG
+ | COLLATION_SCHEMA
+ | COLLATION_NAME
+ | CHARACTER_SET_CATALOG
+ | CHARACTER_SET_SCHEMA
+ | CHARACTER_SET_NAME
+
+<simple value specification 2> ::= <simple value specification>
+
+<item number> ::= <simple value specification>
+
+<get descriptor statement> ::=
+ GET DESCRIPTOR <descriptor name> <get descriptor information>
+
+<get descriptor information> ::=
+ <get count>
+ | VALUE <item number>
+ <get item information> [ { <comma> <get item information> }... ]
+
+<get count> ::=
+ <simple target specification 1> <equals operator>
+ COUNT
+
+<simple target specification 1> ::= <simple target specification>
+
+<simple target specification> ::=
+ <parameter name>
+ | <embedded variable name>
+
+<get item information> ::=
+ <simple target specification 2> <equals operator> <descriptor item name>>
+
+<simple target specification 2> ::= <simple target specification>
+
+<prepare statement> ::=
+ PREPARE <SQL statement name> FROM <SQL statement variable>
+
+<SQL statement name> ::=
+ <statement name>
+ | <extended statement name>
+
+<extended statement name> ::=
+ [ <scope option> ] <simple value specification>
+
+<SQL statement variable> ::= <simple value specification>
+
+<deallocate prepared statement> ::=
+ DEALLOCATE PREPARE <SQL statement name>
+
+<describe statement> ::=
+ <describe input statement>
+ | <describe output statement>
+
+<describe input statement> ::=
+ DESCRIBE INPUT <SQL statement name> <using descriptor>
+
+<using descriptor> ::=
+ { USING | INTO } SQL DESCRIPTOR <descriptor name>
+
+<describe output statement> ::=
+ DESCRIBE [ OUTPUT ] <SQL statement name> <using descriptor>
+
+<execute statement> ::=
+ EXECUTE <SQL statement name>
+ [ <result using clause> ]
+ [ <parameter using clause> ]
+
+<result using clause> ::= <using clause>
+
+<using clause> ::=
+ <using arguments>
+ | <using descriptor>
+
+<using arguments> ::=
+ { USING | INTO } <argument> [ { <comma> <argument> }... ]
+
+<argument> ::= <target specification>
+
+<parameter using clause> ::= <using clause>
+
+<execute immediate statement> ::=
+ EXECUTE IMMEDIATE <SQL statement variable>
+
+<SQL dynamic data statement> ::=
+ <allocate cursor statement>
+ | <dynamic open statement>
+ | <dynamic fetch statement>
+ | <dynamic close statement>
+ | <dynamic delete statement: positioned>
+ | <dynamic update statement: positioned>
+
+<allocate cursor statement> ::=
+ ALLOCATE <extended cursor name> [ INSENSITIVE ]
+ [ SCROLL ] CURSOR
+ FOR <extended statement name>
+
+<extended cursor name> ::=
+ [ <scope option> ] <simple value specification>
+
+<dynamic open statement> ::=
+ OPEN <dynamic cursor name> [ <using clause> ]
+
+<dynamic cursor name> ::=
+ <cursor name>
+ | <extended cursor name>
+
+<dynamic fetch statement> ::=
+ FETCH [ [ <fetch orientation> ] FROM ] <dynamic cursor name>
+ <using clause>
+
+<dynamic close statement> ::=
+ CLOSE <dynamic cursor name>
+
+<dynamic delete statement: positioned> ::=
+ DELETE FROM <table name>
+ WHERE CURRENT OF
+ <dynamic cursor name>
+
+<dynamic update statement: positioned> ::=
+ UPDATE <table name>
+ SET <set clause>
+ [ { <comma> <set clause> }... ]
+ WHERE CURRENT OF
+ <dynamic cursor name>
+
+<SQL diagnostics statement> ::=
+ <get diagnostics statement>
+
+<get diagnostics statement> ::=
+ GET DIAGNOSTICS <sql diagnostics information>
+
+<sql diagnostics information> ::=
+ <statement information>
+ | <condition information>
+
+<statement information> ::=
+ <statement information item> [ { <comma> <statement information item> }... ]
+
+<statement information item> ::=
+ <simple target specification> <equals operator> <statement information item name>
+
+<statement information item name> ::=
+ NUMBER
+ | MORE
+ | COMMAND_FUNCTION
+ | DYNAMIC_FUNCTION
+ | ROW_COUNT
+
+<condition information> ::=
+ EXCEPTION <condition number>
+ <condition information item> [ { <comma> <condition information item> }... ]
+
+<condition number> ::= <simple value specification>
+
+<condition information item> ::=
+ <simple target specification> <equals operator> <condition information item name>
+
+<condition information item name> ::=
+ CONDITION_NUMBER
+ | RETURNED_SQLSTATE
+ | CLASS_ORIGIN
+ | SUBCLASS_ORIGIN
+ | SERVER_NAME
+ | CONNECTION_NAME
+ | CONSTRAINT_CATALOG
+ | CONSTRAINT_SCHEMA
+ | CONSTRAINT_NAME
+ | CATALOG_NAME
+ | SCHEMA_NAME
+ | TABLE_NAME
+ | COLUMN_NAME
+ | CURSOR_NAME
+ | MESSAGE_TEXT
+ | MESSAGE_LENGTH
+ | MESSAGE_OCTET_LENGTH
+
+<embedded SQL host program> ::=
+ <embedded SQL Ada program>
+ | <embedded SQL C program>
+ | <embedded SQL COBOL program>
+ | <embedded SQL Fortran program>
+ | <embedded SQL MUMPS program>
+ | <embedded SQL Pascal program>
+ | <embedded SQL PL/I program>
+
+<embedded SQL Ada program> ::= !! <EMPHASIS>(See the Syntax Rules.)
+
+<embedded SQL C program> ::=
+ !! <EMPHASIS>(See the Syntax Rules.)
+
+<embedded SQL COBOL program> ::= !! <EMPHASIS>(See the Syntax Rules.)
+
+<embedded SQL Fortran program> ::=
+ !! <EMPHASIS>(See the Syntax Rules.)
+
+<embedded SQL MUMPS program> ::= !! <EMPHASIS>(See the Syntax Rules.)
+
+<embedded SQL Pascal program> ::=
+ !! <EMPHASIS>(See the Syntax Rules.)
+
+<embedded SQL PL/I program> ::= !! <EMPHASIS>(See the Syntax Rules.)
+
+<embedded SQL declare section> ::=
+ <embedded SQL begin declare>
+ [ <embedded character set declaration> ]
+ [ <host variable definition>... ]
+ <embedded SQL end declare>
+ | <embedded SQL MUMPS declare>
+
+<embedded SQL begin declare> ::=
+ <SQL prefix> BEGIN DECLARE SECTION
+ [ <SQL terminator> ]
+
+<SQL prefix> ::=
+ EXEC SQL
+ | <ampersand>SQL<left paren>
+
+<SQL terminator> ::=
+ END-EXEC
+ | <semicolon>
+ | <right paren>
+
+<embedded character set declaration> ::=
+ SQL NAMES ARE <character set specification>
+
+<host variable definition> ::=
+ <Ada variable definition>
+ | <C variable definition>
+ | <COBOL variable definition>
+ | <Fortran variable definition>
+ | <MUMPS variable definition>
+ | <Pascal variable definition>
+ | <PL/I variable definition>
+
+<Ada variable definition> ::=
+ <Ada host identifier> [ { <comma> <Ada host identifier> }... ] :
+ <Ada type specification> [ <Ada initial value> ]
+
+<Ada type specification> ::=
+ <Ada qualified type specification>
+ | <Ada unqualified type specification>
+
+<Ada qualified type specification> ::=
+ SQL_STANDARD.CHAR [ CHARACTER SET
+ [ IS ] <character set specification> ]
+ <left paren> 1 <double period> <length> <right paren>
+ | SQL_STANDARD.BIT
+ <left paren> 1 <double period> <length> <right paren>
+ | SQL_STANDARD.SMALLINT
+ | SQL_STANDARD.INT
+ | SQL_STANDARD.REAL
+ | SQL_STANDARD.DOUBLE_PRECISION
+ | SQL_STANDARD.SQLCODE_TYPE
+ | SQL_STANDARD.SQLSTATE_TYPE
+ | SQL_STANDARD.INDICATOR_TYPE
+
+<Ada unqualified type specification> ::=
+ CHAR
+ <left paren> 1 <double period> <length> <right paren>
+ | BIT
+ <left paren> 1 <double period> <length> <right paren>
+ | SMALLINT
+ | INT
+ | REAL
+ | DOUBLE_PRECISION
+ | SQLCODE_TYPE
+ | SQLSTATE_TYPE
+ | INDICATOR_TYPE
+
+<Ada initial value> ::=
+ <Ada assignment operator> <character representation>...
+
+<Ada assignment operator> ::= <colon><equals operator>
+
+<C variable definition> ::=
+ [ <C storage class> ]
+ [ <C class modifier> ]
+ <C variable specification>
+ <semicolon>
+
+<C storage class> ::=
+ auto
+ | extern
+ | static
+
+<C class modifier> ::= const | volatile
+
+<C variable specification> ::=
+ <C numeric variable>
+ | <C character variable>
+ | <C derived variable>
+
+<C numeric variable> ::=
+ { long | short | float | double }
+ <C host identifier> [ <C initial value> ]
+ [ { <comma> <C host identifier> [ <C initial value> ] }... ]
+
+<C initial value> ::=
+ <equals operator> <character representation>...
+
+<C character variable> ::=
+ char [ CHARACTER SET
+ [ IS ] <character set specification> ]
+ <C host identifier>
+ <C array specification> [ <C initial value> ]
+ [ { <comma> <C host identifier>
+ <C array specification>
+ [ <C initial value> ] }... ]
+
+<C array specification> ::=
+ <left bracket> <length> <right bracket>
+
+<C derived variable> ::=
+ <C VARCHAR variable>
+ | <C bit variable>
+
+<C VARCHAR variable> ::=
+ VARCHAR [ CHARACTER SET [ IS ]
+ <character set specification> ]
+ <C host identifier>
+ <C array specification> [ <C initial value> ]
+ [ { <comma> <C host identifier>
+ <C array specification>
+ [ <C initial value> ] }... ]
+
+<C bit variable> ::=
+ BIT <C host identifier>
+ <C array specification> [ <C initial value> ]
+ [ { <comma> <C host identifier>
+ <C array specification>
+ [ <C initial value> ] }... ]
+
+<COBOL variable definition> ::=
+ {01|77} <COBOL host identifier> <COBOL type specification>
+ [ <character representation>... ] <period>
+
+<COBOL type specification> ::=
+ <COBOL character type>
+ | <COBOL bit type>
+ | <COBOL numeric type>
+ | <COBOL integer type>
+
+<COBOL character type> ::=
+ [ CHARACTER SET [ IS ]
+ <character set specification> ]
+ { PIC | PICTURE } [ IS ] { X [ <left paren> <length> <right paren> ] }...
+
+<COBOL bit type> ::=
+ { PIC | PICTURE } [ IS ]
+ { B [ <left paren> <length> <right paren> ] }...
+
+<COBOL numeric type> ::=
+ { PIC | PICTURE } [ IS ]
+ S <COBOL nines specification>
+ [ USAGE [ IS ] ] DISPLAY SIGN LEADING SEPARATE
+
+<COBOL nines specification> ::=
+ <COBOL nines> [ V [ <COBOL nines> ] ]
+ | V <COBOL nines>
+
+<COBOL nines> ::= { 9 [ <left paren> <length> <right paren> ] }...
+
+<COBOL integer type> ::=
+ <COBOL computational integer>
+ | <COBOL binary integer>
+
+<COBOL computational integer> ::=
+ { PIC | PICTURE } [ IS ] S<COBOL nines>
+ [ USAGE [ IS ] ] { COMP | COMPUTATIONAL }
+
+<COBOL binary integer> ::=
+ { PIC | PICTURE } [ IS ] S<COBOL nines>
+ [ USAGE [ IS ] ] BINARY
+
+<Fortran variable definition> ::=
+ <Fortran type specification>
+ <Fortran host identifier>
+ [ { <comma> <Fortran host identifier> }... ]
+
+<Fortran type specification> ::=
+ CHARACTER [ <asterisk> <length> ]
+ [ CHARACTER SET [ IS ]
+ <character set specification> ]
+ | BIT [ <asterisk> <length> ]
+ | INTEGER
+ | REAL
+ | DOUBLE PRECISION
+
+<MUMPS variable definition> ::=
+ { <MUMPS numeric variable> | <MUMPS character variable> }
+ <semicolon>
+
+<MUMPS numeric variable> ::=
+ <MUMPS type specification>
+ <MUMPS host identifier> [ { <comma> <MUMPS host identifier> }... ]
+
+<MUMPS type specification> ::=
+ INT
+ | DEC
+ [ <left paren> <precision> [ <comma> <scale> ] <right paren> ]
+ | REAL
+
+<MUMPS character variable> ::=
+ VARCHAR <MUMPS host identifier> <MUMPS length specification>
+ [ { <comma> <MUMPS host identifier> <MUMPS length specification> }... ]
+
+<MUMPS length specification> ::=
+ <left paren> <length> <right paren>
+
+<Pascal variable definition> ::=
+ <Pascal host identifier> [ { <comma> <Pascal host identifier> }... ] <colon>
+ <Pascal type specification> <semicolon>
+
+<Pascal type specification> ::=
+ PACKED ARRAY
+ <left bracket> 1 <double period> <length> <right bracket>
+ OF CHAR
+ [ CHARACTER SET [ IS ]
+ <character set specification> ]
+ | PACKED ARRAY
+ <left bracket> 1 <double period> <length> <right bracket>
+ OF BIT
+ | INTEGER
+ | REAL
+ | CHAR [ CHARACTER SET
+ [ IS ] <character set specification> ]
+ | BIT
+
+<PL/I variable definition> ::=
+ {DCL | DECLARE}
+ { <PL/I host identifier>
+ | <left paren> <PL/I host identifier>
+ [ { <comma> <PL/I host identifier> }... ] <right paren> }
+ <PL/I type specification>
+ [ <character representation>... ] <semicolon>
+
+<PL/I type specification> ::=
+ { CHAR | CHARACTER } [ VARYING ]
+ <left paren><length><right paren>
+ [ CHARACTER SET
+ [ IS ] <character set specification> ]
+ | BIT [ VARYING ] <left paren><length><right paren>
+ | <PL/I type fixed decimal> <left paren> <precision>
+ [ <comma> <scale> ] <right paren>
+ | <PL/I type fixed binary> [ <left paren> <precision> <right paren> ]
+ | <PL/I type float binary> <left paren> <precision> <right paren>
+
+<PL/I type fixed decimal> ::=
+ { DEC | DECIMAL } FIXED
+ | FIXED { DEC | DECIMAL }
+
+<PL/I type fixed binary> ::=
+ { BIN | BINARY } FIXED
+ | FIXED { BIN | BINARY }
+
+<PL/I type float binary> ::=
+ { BIN | BINARY } FLOAT
+ | FLOAT { BIN | BINARY }
+
+<embedded SQL end declare> ::=
+ <SQL prefix> END DECLARE SECTION
+ [ <SQL terminator> ]
+
+<embedded SQL MUMPS declare> ::=
+ <SQL prefix>
+ BEGIN DECLARE SECTION
+ [ <embedded character set declaration> ]
+ [ <host variable definition>... ]
+ END DECLARE SECTION
+ <SQL terminator>
+
+<embedded SQL statement> ::=
+ <SQL prefix>
+ <statement or declaration>
+ [ <SQL terminator> ]
+
+<statement or declaration> ::=
+ <declare cursor>
+ | <dynamic declare cursor>
+ | <temporary table declaration>
+ | <embedded exception declaration>
+ | <SQL procedure statement>
+
+<embedded exception declaration> ::=
+ WHENEVER <condition> <condition action>
+
+<condition> ::=
+ SQLERROR | NOT FOUND
+
+<condition action> ::=
+ CONTINUE | <go to>
+
+<go to> ::=
+ { GOTO | GO TO } <goto target>
+
+<goto target> ::=
+ <host label identifier>
+ | <unsigned integer>
+ | <host PL/I label variable>
+
+<host label identifier> ::= !!<EMPHASIS>(See the Syntax Rules.)
+
+<host PL/I label variable> ::= !!<EMPHASIS>(See the Syntax Rules.)
+
+<preparable statement> ::=
+ <preparable SQL data statement>
+ | <preparable SQL schema statement>
+ | <preparable SQL transaction statement>
+ | <preparable SQL session statement>
+ | <preparable implementation-defined statement>
+
+<preparable SQL data statement> ::=
+ <delete statement: searched>
+ | <dynamic single row select statement>
+ | <insert statement>
+ | <dynamic select statement>
+ | <update statement: searched>
+ | <preparable dynamic delete statement: positioned>
+ | <preparable dynamic update statement: positioned>
+
+<dynamic single row select statement> ::= <query specification>
+
+<dynamic select statement> ::= <cursor specification>
+
+<preparable dynamic delete statement: positioned> ::=
+ DELETE [ FROM <table name> ]
+ WHERE CURRENT OF <cursor name>
+
+<preparable dynamic update statement: positioned> ::=
+ UPDATE [ <table name> ]
+ SET <set clause list>
+ WHERE CURRENT OF <cursor name>
+
+<preparable SQL schema statement> ::=
+ <SQL schema statement>
+
+<preparable SQL transaction statement> ::=
+ <SQL transaction statement>
+
+<preparable SQL session statement> ::=
+ <SQL session statement>
+
+<preparable implementation-defined statement> ::=
+ !! <EMPHASIS>(See the Syntax Rules.)
+
+<direct SQL statement> ::=
+ <directly executable statement> <semicolon>
+
+<directly executable statement> ::=
+ <direct SQL data statement>
+ | <SQL schema statement>
+ | <SQL transaction statement>
+ | <SQL connection statement>
+ | <SQL session statement>
+ | <direct implementation-defined statement>
+
+<direct SQL data statement> ::=
+ <delete statement: searched>
+ | <direct select statement: multiple rows>
+ | <insert statement>
+ | <update statement: searched>
+ | <temporary table declaration>
+
+<direct select statement: multiple rows> ::=
+ <query expression> [ <order by clause> ]
+
+<direct implementation-defined statement> ::=
+ !!<EMPHASIS>(See the Syntax Rules)
+
+<SQL object identifier> ::=
+ <SQL provenance> <SQL variant>
+
+<SQL provenance> ::= <arc1> <arc2> <arc3>
+
+<arc1> ::= iso | 1 | iso <left paren> 1 <right paren>
+
+<arc2> ::= standard | 0 | standard <left paren> 0 <right paren>
+
+<arc3> ::= 9075
+
+<SQL variant> ::= <SQL edition> <SQL conformance>
+
+<SQL edition> ::= <1987> | <1989> | <1992>
+
+<1987> ::= 0 | edition1987 <left paren> 0 <right paren>
+
+<1989> ::= <1989 base> <1989 package>
+
+<1989 base> ::= 1 | edition1989 <left paren> 1 <right paren>
+
+<1989 package> ::= <integrity no> | <integrity yes>
+
+<integrity no> ::= 0 | IntegrityNo <left paren> 0 <right paren>
+
+<integrity yes> ::= 1 | IntegrityYes <left paren> 1 <right paren>
+
+<1992> ::= 2 | edition1992 <left paren> 2 <right paren>
+
+<SQL conformance> ::= <low> | <intermediate> | <high>
+
+<low> ::= 0 | Low <left paren> 0 <right paren>
+
+<intermediate> ::= 1 | Intermediate <left paren> 1 <right paren>
+
+<high> ::= 2 | High <left paren> 2 <right paren>
+
Property changes on: branches/ddl_sequencer/extensions/dna-sequencer-ddl/target/classes/sql2bnf.aug92.txt
___________________________________________________________________
Name: svn:mime-type
+ text/plain
Added: branches/ddl_sequencer/extensions/dna-sequencer-ddl/target/surefire-reports/TEST-org.jboss.dna.sequencer.ddl.BasicDdlParserTest.xml
===================================================================
--- branches/ddl_sequencer/extensions/dna-sequencer-ddl/target/surefire-reports/TEST-org.jboss.dna.sequencer.ddl.BasicDdlParserTest.xml (rev 0)
+++ branches/ddl_sequencer/extensions/dna-sequencer-ddl/target/surefire-reports/TEST-org.jboss.dna.sequencer.ddl.BasicDdlParserTest.xml 2009-10-02 16:13:40 UTC (rev 1280)
@@ -0,0 +1,130 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<testsuite failures="0" time="0.162" errors="1" skipped="0" tests="5" name="org.jboss.dna.sequencer.ddl.BasicDdlParserTest">
+ <properties>
+ <property name="java.vendor" value="Sun Microsystems Inc."/>
+ <property name="env.SESSION_MANAGER" value="local/work-laptop:/tmp/.ICE-unix/5913"/>
+ <property name="localRepository" value="/home/blafond/.m2/repository"/>
+ <property name="sun.java.launcher" value="SUN_STANDARD"/>
+ <property name="sun.management.compiler" value="HotSpot Tiered Compilers"/>
+ <property name="os.name" value="Linux"/>
+ <property name="sun.boot.class.path" value="/usr/lib/jvm/java-6-sun-1.6.0.14/jre/lib/resources.jar:/usr/lib/jvm/java-6-sun-1.6.0.14/jre/lib/rt.jar:/usr/lib/jvm/java-6-sun-1.6.0.14/jre/lib/sunrsasign.jar:/usr/lib/jvm/java-6-sun-1.6.0.14/jre/lib/jsse.jar:/usr/lib/jvm/java-6-sun-1.6.0.14/jre/lib/jce.jar:/usr/lib/jvm/java-6-sun-1.6.0.14/jre/lib/charsets.jar:/usr/lib/jvm/java-6-sun-1.6.0.14/jre/classes"/>
+ <property name="env.PWD" value="/home/blafond"/>
+ <property name="env.XDG_SESSION_COOKIE" value="70bef359dccaf87f474bc0d7490f06a9-1253116029.282562-1962947517"/>
+ <property name="sun.desktop" value="gnome"/>
+ <property name="env.LANG" value="en_US.UTF-8"/>
+ <property name="java.vm.specification.vendor" value="Sun Microsystems Inc."/>
+ <property name="java.runtime.version" value="1.6.0_14-b08"/>
+ <property name="env.DISPLAY" value=":0.0"/>
+ <property name="user.name" value="blafond"/>
+ <property name="env.USER" value="blafond"/>
+ <property name="env.SHELL" value="/bin/bash"/>
+ <property name="env.MOZILLA_FIVE_HOME" value="/usr/lib/xulrunner-addons"/>
+ <property name="env.DESKTOP_SESSION" value="default"/>
+ <property name="env.XDG_DATA_DIRS" value="/usr/local/share/:/usr/share/:/usr/share/gdm/"/>
+ <property name="env.NLSPATH" value="/usr/dt/lib/nls/msg/%L/%N.cat"/>
+ <property name="env.PATH" value="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games"/>
+ <property name="user.language" value="en"/>
+ <property name="sun.boot.library.path" value="/usr/lib/jvm/java-6-sun-1.6.0.14/jre/lib/i386"/>
+ <property name="classworlds.conf" value="/home/blafond/Workspaces/DNA/.metadata/.plugins/org.maven.ide.eclipse/launches/m2conf7839333797857365463.tmp"/>
+ <property name="java.version" value="1.6.0_14"/>
+ <property name="user.timezone" value="US/Central"/>
+ <property name="env.DBUS_SESSION_BUS_ADDRESS" value="unix:abstract=/tmp/dbus-Cmyp7m4oLS,guid=f006087070ce2e1077eb8f884ab1087e"/>
+ <property name="sun.arch.data.model" value="32"/>
+ <property name="java.endorsed.dirs" value="/usr/lib/jvm/java-6-sun-1.6.0.14/jre/lib/endorsed"/>
+ <property name="sun.cpu.isalist" value=""/>
+ <property name="sun.jnu.encoding" value="UTF-8"/>
+ <property name="file.encoding.pkg" value="sun.io"/>
+ <property name="file.separator" value="/"/>
+ <property name="java.specification.name" value="Java Platform API Specification"/>
+ <property name="env.GNOME_DESKTOP_SESSION_ID" value="Default"/>
+ <property name="java.class.version" value="50.0"/>
+ <property name="env.GDMSESSION" value="default"/>
+ <property name="user.country" value="US"/>
+ <property name="env.GNOME_KEYRING_PID" value="5912"/>
+ <property name="java.home" value="/usr/lib/jvm/java-6-sun-1.6.0.14/jre"/>
+ <property name="java.vm.info" value="mixed mode"/>
+ <property name="env.LOGNAME" value="blafond"/>
+ <property name="os.version" value="2.6.24-24-generic"/>
+ <property name="path.separator" value=":"/>
+ <property name="java.vm.version" value="14.0-b16"/>
+ <property name="java.awt.printerjob" value="sun.print.PSPrinterJob"/>
+ <property name="env.WINDOWPATH" value="7"/>
+ <property name="sun.io.unicode.encoding" value="UnicodeLittle"/>
+ <property name="env.GDM_LANG" value="en_US.UTF-8"/>
+ <property name="user.home" value="/home/blafond"/>
+ <property name="java.specification.vendor" value="Sun Microsystems Inc."/>
+ <property name="java.library.path" value="/usr/lib/jvm/java-6-sun-1.6.0.14/jre/lib/i386/server:/usr/lib/jvm/java-6-sun-1.6.0.14/jre/lib/i386:/usr/lib/jvm/java-6-sun-1.6.0.14/jre/../lib/i386:/usr/lib/jvm/java-6-openjdk/jre/lib/i386/client:/usr/lib/jvm/java-6-openjdk/jre/lib/i386:/usr/lib/xulrunner-addons:/usr/lib/xulrunner-addons:/usr/lib/xulrunner-addons:/usr/java/packages/lib/i386:/lib:/usr/lib"/>
+ <property name="java.vendor.url" value="http://java.sun.com/"/>
+ <property name="env.GDM_XSERVER_LOCATION" value="local"/>
+ <property name="java.vm.vendor" value="Sun Microsystems Inc."/>
+ <property name="maven.home" value="EMBEDDED"/>
+ <property name="java.runtime.name" value="Java(TM) SE Runtime Environment"/>
+ <property name="java.class.path" value="/home/blafond/Programs/eclipse-SDK-3.5/plugins/org.maven.ide.components.maven_embedder_2.1.0.20080530-2300/jars/plexus-classworlds-1.2-alpha-12.jar"/>
+ <property name="env.XFILESEARCHPATH" value="/usr/dt/app-defaults/%L/Dt"/>
+ <property name="java.vm.specification.name" value="Java Virtual Machine Specification"/>
+ <property name="java.vm.specification.version" value="1.0"/>
+ <property name="m2eclipse.workspace.state" value="/home/blafond/Workspaces/DNA/.metadata/.plugins/org.maven.ide.eclipse/workspacestate.properties"/>
+ <property name="sun.cpu.endian" value="little"/>
+ <property name="env.GTK_RC_FILES" value="/etc/gtk/gtkrc:/home/blafond/.gtkrc-1.2-gnome2"/>
+ <property name="sun.os.patch.level" value="unknown"/>
+ <property name="env.HOME" value="/home/blafond"/>
+ <property name="surefire.test.class.path" value="/home/blafond/Workspaces/DNA/dna/extensions/dna-sequencer-ddl/target/test-classes:/home/blafond/Workspaces/DNA/dna/extensions/dna-sequencer-ddl/target/classes:/home/blafond/.m2/repository/hsqldb/hsqldb/1.8.0.2/hsqldb-1.8.0.2.jar:/home/blafond/.m2/repository/org/jboss/dna/dna-common/0.7-SNAPSHOT/dna-common-0.7-SNAPSHOT.jar:/home/blafond/.m2/repository/org/slf4j/slf4j-api/1.5.8/slf4j-api-1.5.8.jar:/home/blafond/.m2/repository/net/jcip/jcip-annotations/1.0/jcip-annotations-1.0.jar:/home/blafond/.m2/repository/org/jboss/dna/dna-graph/0.7-SNAPSHOT/dna-graph-0.7-SNAPSHOT.jar:/home/blafond/.m2/repository/joda-time/joda-time/1.4/joda-time-1.4.jar:/home/blafond/.m2/repository/com/google/code/google-collections/google-collect/snapshot-20080530/google-collect-snapshot-20080530.jar:/home/blafond/.m2/repository/org/jboss/dna/dna-common/0.7-SNAPSHOT/dna-common-0.7-SNAPSHOT-tests.jar:/home/blafond/.m2/repository/org/jboss/dna/dna-graph/!
0.7-SNAPSHOT/dna-graph-0.7-SNAPSHOT-tests.jar:/home/blafond/.m2/repository/junit/junit/4.4/junit-4.4.jar:/home/blafond/.m2/repository/org/hamcrest/hamcrest-library/1.1/hamcrest-library-1.1.jar:/home/blafond/.m2/repository/org/hamcrest/hamcrest-core/1.1/hamcrest-core-1.1.jar:/home/blafond/.m2/repository/org/mockito/mockito-all/1.5/mockito-all-1.5.jar:/home/blafond/.m2/repository/org/slf4j/slf4j-log4j12/1.5.8/slf4j-log4j12-1.5.8.jar:/home/blafond/.m2/repository/log4j/log4j/1.2.14/log4j-1.2.14.jar:"/>
+ <property name="java.io.tmpdir" value="/home/blafond/Workspaces/DNA/dna/extensions/dna-sequencer-ddl/target"/>
+ <property name="env.LD_LIBRARY_PATH" value="/usr/lib/jvm/java-6-sun-1.6.0.14/jre/lib/i386/server:/usr/lib/jvm/java-6-sun-1.6.0.14/jre/lib/i386:/usr/lib/jvm/java-6-sun-1.6.0.14/jre/../lib/i386:/usr/lib/jvm/java-6-openjdk/jre/lib/i386/client:/usr/lib/jvm/java-6-openjdk/jre/lib/i386:/usr/lib/xulrunner-addons:/usr/lib/xulrunner-addons:/usr/lib/xulrunner-addons"/>
+ <property name="java.vendor.url.bug" value="http://java.sun.com/cgi-bin/bugreport.cgi"/>
+ <property name="env.SSH_AUTH_SOCK" value="/tmp/keyring-dF941n/ssh"/>
+ <property name="java.awt.graphicsenv" value="sun.awt.X11GraphicsEnvironment"/>
+ <property name="os.arch" value="i386"/>
+ <property name="java.ext.dirs" value="/usr/lib/jvm/java-6-sun-1.6.0.14/jre/lib/ext:/usr/java/packages/lib/ext"/>
+ <property name="user.dir" value="/home/blafond/Workspaces/DNA/dna/extensions/dna-sequencer-ddl"/>
+ <property name="env.XAUTHORITY" value="/home/blafond/.Xauthority"/>
+ <property name="line.separator" value="
+"/>
+ <property name="java.vm.name" value="Java HotSpot(TM) Server VM"/>
+ <property name="basedir" value="/home/blafond/Workspaces/DNA/dna/extensions/dna-sequencer-ddl"/>
+ <property name="maven.mode.standalone" value="true"/>
+ <property name="env.USERNAME" value="blafond"/>
+ <property name="file.encoding" value="UTF-8"/>
+ <property name="env.GNOME_KEYRING_SOCKET" value="/tmp/keyring-dF941n/socket"/>
+ <property name="env.GPG_AGENT_INFO" value="/tmp/seahorse-ZO5q59/S.gpg-agent:5994:1"/>
+ <property name="java.specification.version" value="1.6"/>
+ </properties>
+ <testcase time="0.04" classname="org.jboss.dna.sequencer.ddl.BasicDdlParserTest" name="shouldParseColumnDefinition"/>
+ <testcase time="0.038" classname="org.jboss.dna.sequencer.ddl.BasicDdlParserTest" name="shouldGetTableElementString"/>
+ <testcase time="0.028" classname="org.jboss.dna.sequencer.ddl.BasicDdlParserTest" name="shouldParseCreateTable"/>
+ <testcase time="0.027" classname="org.jboss.dna.sequencer.ddl.BasicDdlParserTest" name="shouldParseCreateTableWithConstraint"/>
+ <testcase time="0.022" classname="org.jboss.dna.sequencer.ddl.BasicDdlParserTest" name="shouldParseCreateTables">
+ <error type="java.lang.NullPointerException">java.lang.NullPointerException
+ at org.jboss.dna.sequencer.ddl.BasicDdlParserTest.getFileContent(BasicDdlParserTest.java:59)
+ at org.jboss.dna.sequencer.ddl.BasicDdlParserTest.shouldParseCreateTables(BasicDdlParserTest.java:159)
+ at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
+ at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
+ at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
+ at java.lang.reflect.Method.invoke(Method.java:597)
+ at org.junit.internal.runners.TestMethod.invoke(TestMethod.java:59)
+ at org.junit.internal.runners.MethodRoadie.runTestMethod(MethodRoadie.java:98)
+ at org.junit.internal.runners.MethodRoadie$2.run(MethodRoadie.java:79)
+ at org.junit.internal.runners.MethodRoadie.runBeforesThenTestThenAfters(MethodRoadie.java:87)
+ at org.junit.internal.runners.MethodRoadie.runTest(MethodRoadie.java:77)
+ at org.junit.internal.runners.MethodRoadie.run(MethodRoadie.java:42)
+ at org.junit.internal.runners.JUnit4ClassRunner.invokeTestMethod(JUnit4ClassRunner.java:88)
+ at org.junit.internal.runners.JUnit4ClassRunner.runMethods(JUnit4ClassRunner.java:51)
+ at org.junit.internal.runners.JUnit4ClassRunner$1.run(JUnit4ClassRunner.java:44)
+ at org.junit.internal.runners.ClassRoadie.runUnprotected(ClassRoadie.java:27)
+ at org.junit.internal.runners.ClassRoadie.runProtected(ClassRoadie.java:37)
+ at org.junit.internal.runners.JUnit4ClassRunner.run(JUnit4ClassRunner.java:42)
+ at org.apache.maven.surefire.junit4.JUnit4TestSet.execute(JUnit4TestSet.java:62)
+ at org.apache.maven.surefire.suite.AbstractDirectoryTestSuite.executeTestSet(AbstractDirectoryTestSuite.java:140)
+ at org.apache.maven.surefire.suite.AbstractDirectoryTestSuite.execute(AbstractDirectoryTestSuite.java:127)
+ at org.apache.maven.surefire.Surefire.run(Surefire.java:177)
+ at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
+ at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
+ at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
+ at java.lang.reflect.Method.invoke(Method.java:597)
+ at org.apache.maven.surefire.booter.SurefireBooter.runSuitesInProcess(SurefireBooter.java:338)
+ at org.apache.maven.surefire.booter.SurefireBooter.main(SurefireBooter.java:997)
+</error>
+ <system-out> Getting Content for File = src/test/resources/ddl/createTables.ddl
+java.io.FileNotFoundException: src/test/resources/ddl/createTables.ddl (No such file or directory)</system-out>
+ </testcase>
+</testsuite>
\ No newline at end of file
Property changes on: branches/ddl_sequencer/extensions/dna-sequencer-ddl/target/surefire-reports/TEST-org.jboss.dna.sequencer.ddl.BasicDdlParserTest.xml
___________________________________________________________________
Name: svn:mime-type
+ text/plain
Added: branches/ddl_sequencer/extensions/dna-sequencer-ddl/target/surefire-reports/TEST-org.jboss.dna.sequencer.ddl.datatype.DataTypeParserTest.xml
===================================================================
--- branches/ddl_sequencer/extensions/dna-sequencer-ddl/target/surefire-reports/TEST-org.jboss.dna.sequencer.ddl.datatype.DataTypeParserTest.xml (rev 0)
+++ branches/ddl_sequencer/extensions/dna-sequencer-ddl/target/surefire-reports/TEST-org.jboss.dna.sequencer.ddl.datatype.DataTypeParserTest.xml 2009-10-02 16:13:40 UTC (rev 1280)
@@ -0,0 +1,120 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<testsuite failures="0" time="0.276" errors="0" skipped="0" tests="28" name="org.jboss.dna.sequencer.ddl.datatype.DataTypeParserTest">
+ <properties>
+ <property name="java.vendor" value="Sun Microsystems Inc."/>
+ <property name="env.SESSION_MANAGER" value="local/work-laptop:/tmp/.ICE-unix/5913"/>
+ <property name="localRepository" value="/home/blafond/.m2/repository"/>
+ <property name="sun.java.launcher" value="SUN_STANDARD"/>
+ <property name="sun.management.compiler" value="HotSpot Tiered Compilers"/>
+ <property name="os.name" value="Linux"/>
+ <property name="sun.boot.class.path" value="/usr/lib/jvm/java-6-sun-1.6.0.14/jre/lib/resources.jar:/usr/lib/jvm/java-6-sun-1.6.0.14/jre/lib/rt.jar:/usr/lib/jvm/java-6-sun-1.6.0.14/jre/lib/sunrsasign.jar:/usr/lib/jvm/java-6-sun-1.6.0.14/jre/lib/jsse.jar:/usr/lib/jvm/java-6-sun-1.6.0.14/jre/lib/jce.jar:/usr/lib/jvm/java-6-sun-1.6.0.14/jre/lib/charsets.jar:/usr/lib/jvm/java-6-sun-1.6.0.14/jre/classes"/>
+ <property name="env.PWD" value="/home/blafond"/>
+ <property name="env.XDG_SESSION_COOKIE" value="70bef359dccaf87f474bc0d7490f06a9-1253116029.282562-1962947517"/>
+ <property name="sun.desktop" value="gnome"/>
+ <property name="env.LANG" value="en_US.UTF-8"/>
+ <property name="java.vm.specification.vendor" value="Sun Microsystems Inc."/>
+ <property name="java.runtime.version" value="1.6.0_14-b08"/>
+ <property name="env.DISPLAY" value=":0.0"/>
+ <property name="user.name" value="blafond"/>
+ <property name="env.USER" value="blafond"/>
+ <property name="env.SHELL" value="/bin/bash"/>
+ <property name="env.MOZILLA_FIVE_HOME" value="/usr/lib/xulrunner-addons"/>
+ <property name="env.DESKTOP_SESSION" value="default"/>
+ <property name="env.XDG_DATA_DIRS" value="/usr/local/share/:/usr/share/:/usr/share/gdm/"/>
+ <property name="env.NLSPATH" value="/usr/dt/lib/nls/msg/%L/%N.cat"/>
+ <property name="env.PATH" value="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games"/>
+ <property name="user.language" value="en"/>
+ <property name="sun.boot.library.path" value="/usr/lib/jvm/java-6-sun-1.6.0.14/jre/lib/i386"/>
+ <property name="classworlds.conf" value="/home/blafond/Workspaces/DNA/.metadata/.plugins/org.maven.ide.eclipse/launches/m2conf7839333797857365463.tmp"/>
+ <property name="java.version" value="1.6.0_14"/>
+ <property name="user.timezone" value=""/>
+ <property name="env.DBUS_SESSION_BUS_ADDRESS" value="unix:abstract=/tmp/dbus-Cmyp7m4oLS,guid=f006087070ce2e1077eb8f884ab1087e"/>
+ <property name="sun.arch.data.model" value="32"/>
+ <property name="java.endorsed.dirs" value="/usr/lib/jvm/java-6-sun-1.6.0.14/jre/lib/endorsed"/>
+ <property name="sun.cpu.isalist" value=""/>
+ <property name="sun.jnu.encoding" value="UTF-8"/>
+ <property name="file.encoding.pkg" value="sun.io"/>
+ <property name="file.separator" value="/"/>
+ <property name="java.specification.name" value="Java Platform API Specification"/>
+ <property name="env.GNOME_DESKTOP_SESSION_ID" value="Default"/>
+ <property name="java.class.version" value="50.0"/>
+ <property name="env.GDMSESSION" value="default"/>
+ <property name="user.country" value="US"/>
+ <property name="env.GNOME_KEYRING_PID" value="5912"/>
+ <property name="java.home" value="/usr/lib/jvm/java-6-sun-1.6.0.14/jre"/>
+ <property name="java.vm.info" value="mixed mode"/>
+ <property name="env.LOGNAME" value="blafond"/>
+ <property name="os.version" value="2.6.24-24-generic"/>
+ <property name="path.separator" value=":"/>
+ <property name="java.vm.version" value="14.0-b16"/>
+ <property name="java.awt.printerjob" value="sun.print.PSPrinterJob"/>
+ <property name="env.WINDOWPATH" value="7"/>
+ <property name="sun.io.unicode.encoding" value="UnicodeLittle"/>
+ <property name="env.GDM_LANG" value="en_US.UTF-8"/>
+ <property name="user.home" value="/home/blafond"/>
+ <property name="java.specification.vendor" value="Sun Microsystems Inc."/>
+ <property name="java.library.path" value="/usr/lib/jvm/java-6-sun-1.6.0.14/jre/lib/i386/server:/usr/lib/jvm/java-6-sun-1.6.0.14/jre/lib/i386:/usr/lib/jvm/java-6-sun-1.6.0.14/jre/../lib/i386:/usr/lib/jvm/java-6-openjdk/jre/lib/i386/client:/usr/lib/jvm/java-6-openjdk/jre/lib/i386:/usr/lib/xulrunner-addons:/usr/lib/xulrunner-addons:/usr/lib/xulrunner-addons:/usr/java/packages/lib/i386:/lib:/usr/lib"/>
+ <property name="java.vendor.url" value="http://java.sun.com/"/>
+ <property name="env.GDM_XSERVER_LOCATION" value="local"/>
+ <property name="java.vm.vendor" value="Sun Microsystems Inc."/>
+ <property name="maven.home" value="EMBEDDED"/>
+ <property name="java.runtime.name" value="Java(TM) SE Runtime Environment"/>
+ <property name="java.class.path" value="/home/blafond/Programs/eclipse-SDK-3.5/plugins/org.maven.ide.components.maven_embedder_2.1.0.20080530-2300/jars/plexus-classworlds-1.2-alpha-12.jar"/>
+ <property name="env.XFILESEARCHPATH" value="/usr/dt/app-defaults/%L/Dt"/>
+ <property name="java.vm.specification.name" value="Java Virtual Machine Specification"/>
+ <property name="java.vm.specification.version" value="1.0"/>
+ <property name="m2eclipse.workspace.state" value="/home/blafond/Workspaces/DNA/.metadata/.plugins/org.maven.ide.eclipse/workspacestate.properties"/>
+ <property name="sun.cpu.endian" value="little"/>
+ <property name="env.GTK_RC_FILES" value="/etc/gtk/gtkrc:/home/blafond/.gtkrc-1.2-gnome2"/>
+ <property name="sun.os.patch.level" value="unknown"/>
+ <property name="env.HOME" value="/home/blafond"/>
+ <property name="surefire.test.class.path" value="/home/blafond/Workspaces/DNA/dna/extensions/dna-sequencer-ddl/target/test-classes:/home/blafond/Workspaces/DNA/dna/extensions/dna-sequencer-ddl/target/classes:/home/blafond/.m2/repository/hsqldb/hsqldb/1.8.0.2/hsqldb-1.8.0.2.jar:/home/blafond/.m2/repository/org/jboss/dna/dna-common/0.7-SNAPSHOT/dna-common-0.7-SNAPSHOT.jar:/home/blafond/.m2/repository/org/slf4j/slf4j-api/1.5.8/slf4j-api-1.5.8.jar:/home/blafond/.m2/repository/net/jcip/jcip-annotations/1.0/jcip-annotations-1.0.jar:/home/blafond/.m2/repository/org/jboss/dna/dna-graph/0.7-SNAPSHOT/dna-graph-0.7-SNAPSHOT.jar:/home/blafond/.m2/repository/joda-time/joda-time/1.4/joda-time-1.4.jar:/home/blafond/.m2/repository/com/google/code/google-collections/google-collect/snapshot-20080530/google-collect-snapshot-20080530.jar:/home/blafond/.m2/repository/org/jboss/dna/dna-common/0.7-SNAPSHOT/dna-common-0.7-SNAPSHOT-tests.jar:/home/blafond/.m2/repository/org/jboss/dna/dna-graph/!
0.7-SNAPSHOT/dna-graph-0.7-SNAPSHOT-tests.jar:/home/blafond/.m2/repository/junit/junit/4.4/junit-4.4.jar:/home/blafond/.m2/repository/org/hamcrest/hamcrest-library/1.1/hamcrest-library-1.1.jar:/home/blafond/.m2/repository/org/hamcrest/hamcrest-core/1.1/hamcrest-core-1.1.jar:/home/blafond/.m2/repository/org/mockito/mockito-all/1.5/mockito-all-1.5.jar:/home/blafond/.m2/repository/org/slf4j/slf4j-log4j12/1.5.8/slf4j-log4j12-1.5.8.jar:/home/blafond/.m2/repository/log4j/log4j/1.2.14/log4j-1.2.14.jar:"/>
+ <property name="java.io.tmpdir" value="/home/blafond/Workspaces/DNA/dna/extensions/dna-sequencer-ddl/target"/>
+ <property name="env.LD_LIBRARY_PATH" value="/usr/lib/jvm/java-6-sun-1.6.0.14/jre/lib/i386/server:/usr/lib/jvm/java-6-sun-1.6.0.14/jre/lib/i386:/usr/lib/jvm/java-6-sun-1.6.0.14/jre/../lib/i386:/usr/lib/jvm/java-6-openjdk/jre/lib/i386/client:/usr/lib/jvm/java-6-openjdk/jre/lib/i386:/usr/lib/xulrunner-addons:/usr/lib/xulrunner-addons:/usr/lib/xulrunner-addons"/>
+ <property name="java.vendor.url.bug" value="http://java.sun.com/cgi-bin/bugreport.cgi"/>
+ <property name="env.SSH_AUTH_SOCK" value="/tmp/keyring-dF941n/ssh"/>
+ <property name="java.awt.graphicsenv" value="sun.awt.X11GraphicsEnvironment"/>
+ <property name="os.arch" value="i386"/>
+ <property name="java.ext.dirs" value="/usr/lib/jvm/java-6-sun-1.6.0.14/jre/lib/ext:/usr/java/packages/lib/ext"/>
+ <property name="user.dir" value="/home/blafond/Workspaces/DNA/dna/extensions/dna-sequencer-ddl"/>
+ <property name="env.XAUTHORITY" value="/home/blafond/.Xauthority"/>
+ <property name="line.separator" value="
+"/>
+ <property name="java.vm.name" value="Java HotSpot(TM) Server VM"/>
+ <property name="basedir" value="/home/blafond/Workspaces/DNA/dna/extensions/dna-sequencer-ddl"/>
+ <property name="maven.mode.standalone" value="true"/>
+ <property name="env.USERNAME" value="blafond"/>
+ <property name="file.encoding" value="UTF-8"/>
+ <property name="env.GNOME_KEYRING_SOCKET" value="/tmp/keyring-dF941n/socket"/>
+ <property name="env.GPG_AGENT_INFO" value="/tmp/seahorse-ZO5q59/S.gpg-agent:5994:1"/>
+ <property name="java.specification.version" value="1.6"/>
+ </properties>
+ <testcase time="0.028" classname="org.jboss.dna.sequencer.ddl.datatype.DataTypeParserTest" name="shouldParseBracketedInteger"/>
+ <testcase time="0.005" classname="org.jboss.dna.sequencer.ddl.datatype.DataTypeParserTest" name="shouldParseKMGInteger"/>
+ <testcase time="0.006" classname="org.jboss.dna.sequencer.ddl.datatype.DataTypeParserTest" name="shouldParseCHAR"/>
+ <testcase time="0.006" classname="org.jboss.dna.sequencer.ddl.datatype.DataTypeParserTest" name="shouldParseCHARACTER"/>
+ <testcase time="0.006" classname="org.jboss.dna.sequencer.ddl.datatype.DataTypeParserTest" name="shouldParseCHAR_VARYING"/>
+ <testcase time="0.005" classname="org.jboss.dna.sequencer.ddl.datatype.DataTypeParserTest" name="shouldParseCHARACTER_VARYING"/>
+ <testcase time="0.036" classname="org.jboss.dna.sequencer.ddl.datatype.DataTypeParserTest" name="shouldParseVARCHAR"/>
+ <testcase time="0.02" classname="org.jboss.dna.sequencer.ddl.datatype.DataTypeParserTest" name="shouldParseNATIONAL_CHAR"/>
+ <testcase time="0.007" classname="org.jboss.dna.sequencer.ddl.datatype.DataTypeParserTest" name="shouldParseNATIONAL_CHARACTER"/>
+ <testcase time="0.005" classname="org.jboss.dna.sequencer.ddl.datatype.DataTypeParserTest" name="shouldParseNATIONAL_CHAR_VARYING"/>
+ <testcase time="0.005" classname="org.jboss.dna.sequencer.ddl.datatype.DataTypeParserTest" name="shouldParseNATIONAL_CHARACTER_VARYING"/>
+ <testcase time="0.004" classname="org.jboss.dna.sequencer.ddl.datatype.DataTypeParserTest" name="shouldParseNCHAR_VARYING"/>
+ <testcase time="0.005" classname="org.jboss.dna.sequencer.ddl.datatype.DataTypeParserTest" name="shouldParseBIT"/>
+ <testcase time="0.004" classname="org.jboss.dna.sequencer.ddl.datatype.DataTypeParserTest" name="shouldParseBITWithLength"/>
+ <testcase time="0.005" classname="org.jboss.dna.sequencer.ddl.datatype.DataTypeParserTest" name="shouldParseBIT_VARYINGWithLength"/>
+ <testcase time="0.005" classname="org.jboss.dna.sequencer.ddl.datatype.DataTypeParserTest" name="shouldNotParseXXXXXXTYPE"/>
+ <testcase time="0.004" classname="org.jboss.dna.sequencer.ddl.datatype.DataTypeParserTest" name="shouldParseINT"/>
+ <testcase time="0.004" classname="org.jboss.dna.sequencer.ddl.datatype.DataTypeParserTest" name="shouldParseINTEGER"/>
+ <testcase time="0.005" classname="org.jboss.dna.sequencer.ddl.datatype.DataTypeParserTest" name="shouldParseSMALLINT"/>
+ <testcase time="0.009" classname="org.jboss.dna.sequencer.ddl.datatype.DataTypeParserTest" name="shouldParseNUMERIC"/>
+ <testcase time="0.007" classname="org.jboss.dna.sequencer.ddl.datatype.DataTypeParserTest" name="shouldParseDECIMAL"/>
+ <testcase time="0.006" classname="org.jboss.dna.sequencer.ddl.datatype.DataTypeParserTest" name="shouldParseDEC"/>
+ <testcase time="0.007" classname="org.jboss.dna.sequencer.ddl.datatype.DataTypeParserTest" name="shouldParseFLOAT"/>
+ <testcase time="0.005" classname="org.jboss.dna.sequencer.ddl.datatype.DataTypeParserTest" name="shouldParseREAL"/>
+ <testcase time="0.005" classname="org.jboss.dna.sequencer.ddl.datatype.DataTypeParserTest" name="shouldParseDOUBLE_PRECISION"/>
+ <testcase time="0.004" classname="org.jboss.dna.sequencer.ddl.datatype.DataTypeParserTest" name="shouldParseDATE"/>
+ <testcase time="0.005" classname="org.jboss.dna.sequencer.ddl.datatype.DataTypeParserTest" name="shouldParseTIME"/>
+ <testcase time="0.005" classname="org.jboss.dna.sequencer.ddl.datatype.DataTypeParserTest" name="shouldParseTIMESTAMP"/>
+</testsuite>
\ No newline at end of file
Property changes on: branches/ddl_sequencer/extensions/dna-sequencer-ddl/target/surefire-reports/TEST-org.jboss.dna.sequencer.ddl.datatype.DataTypeParserTest.xml
___________________________________________________________________
Name: svn:mime-type
+ text/plain
Added: branches/ddl_sequencer/extensions/dna-sequencer-ddl/target/surefire-reports/TEST-org.jboss.dna.sequencer.ddl.dialect.DerbyDdlParserTest.xml
===================================================================
--- branches/ddl_sequencer/extensions/dna-sequencer-ddl/target/surefire-reports/TEST-org.jboss.dna.sequencer.ddl.dialect.DerbyDdlParserTest.xml (rev 0)
+++ branches/ddl_sequencer/extensions/dna-sequencer-ddl/target/surefire-reports/TEST-org.jboss.dna.sequencer.ddl.dialect.DerbyDdlParserTest.xml 2009-10-02 16:13:40 UTC (rev 1280)
@@ -0,0 +1,127 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<testsuite failures="0" time="2.197" errors="1" skipped="0" tests="2" name="org.jboss.dna.sequencer.ddl.dialect.DerbyDdlParserTest">
+ <properties>
+ <property name="java.vendor" value="Sun Microsystems Inc."/>
+ <property name="env.SESSION_MANAGER" value="local/work-laptop:/tmp/.ICE-unix/5913"/>
+ <property name="localRepository" value="/home/blafond/.m2/repository"/>
+ <property name="sun.java.launcher" value="SUN_STANDARD"/>
+ <property name="sun.management.compiler" value="HotSpot Tiered Compilers"/>
+ <property name="os.name" value="Linux"/>
+ <property name="sun.boot.class.path" value="/usr/lib/jvm/java-6-sun-1.6.0.14/jre/lib/resources.jar:/usr/lib/jvm/java-6-sun-1.6.0.14/jre/lib/rt.jar:/usr/lib/jvm/java-6-sun-1.6.0.14/jre/lib/sunrsasign.jar:/usr/lib/jvm/java-6-sun-1.6.0.14/jre/lib/jsse.jar:/usr/lib/jvm/java-6-sun-1.6.0.14/jre/lib/jce.jar:/usr/lib/jvm/java-6-sun-1.6.0.14/jre/lib/charsets.jar:/usr/lib/jvm/java-6-sun-1.6.0.14/jre/classes"/>
+ <property name="env.PWD" value="/home/blafond"/>
+ <property name="env.XDG_SESSION_COOKIE" value="70bef359dccaf87f474bc0d7490f06a9-1253116029.282562-1962947517"/>
+ <property name="sun.desktop" value="gnome"/>
+ <property name="env.LANG" value="en_US.UTF-8"/>
+ <property name="java.vm.specification.vendor" value="Sun Microsystems Inc."/>
+ <property name="java.runtime.version" value="1.6.0_14-b08"/>
+ <property name="env.DISPLAY" value=":0.0"/>
+ <property name="user.name" value="blafond"/>
+ <property name="env.USER" value="blafond"/>
+ <property name="env.SHELL" value="/bin/bash"/>
+ <property name="env.MOZILLA_FIVE_HOME" value="/usr/lib/xulrunner-addons"/>
+ <property name="env.DESKTOP_SESSION" value="default"/>
+ <property name="env.XDG_DATA_DIRS" value="/usr/local/share/:/usr/share/:/usr/share/gdm/"/>
+ <property name="env.NLSPATH" value="/usr/dt/lib/nls/msg/%L/%N.cat"/>
+ <property name="env.PATH" value="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games"/>
+ <property name="user.language" value="en"/>
+ <property name="sun.boot.library.path" value="/usr/lib/jvm/java-6-sun-1.6.0.14/jre/lib/i386"/>
+ <property name="classworlds.conf" value="/home/blafond/Workspaces/DNA/.metadata/.plugins/org.maven.ide.eclipse/launches/m2conf7839333797857365463.tmp"/>
+ <property name="java.version" value="1.6.0_14"/>
+ <property name="user.timezone" value="US/Central"/>
+ <property name="env.DBUS_SESSION_BUS_ADDRESS" value="unix:abstract=/tmp/dbus-Cmyp7m4oLS,guid=f006087070ce2e1077eb8f884ab1087e"/>
+ <property name="sun.arch.data.model" value="32"/>
+ <property name="java.endorsed.dirs" value="/usr/lib/jvm/java-6-sun-1.6.0.14/jre/lib/endorsed"/>
+ <property name="sun.cpu.isalist" value=""/>
+ <property name="sun.jnu.encoding" value="UTF-8"/>
+ <property name="file.encoding.pkg" value="sun.io"/>
+ <property name="file.separator" value="/"/>
+ <property name="java.specification.name" value="Java Platform API Specification"/>
+ <property name="env.GNOME_DESKTOP_SESSION_ID" value="Default"/>
+ <property name="java.class.version" value="50.0"/>
+ <property name="env.GDMSESSION" value="default"/>
+ <property name="user.country" value="US"/>
+ <property name="env.GNOME_KEYRING_PID" value="5912"/>
+ <property name="java.home" value="/usr/lib/jvm/java-6-sun-1.6.0.14/jre"/>
+ <property name="java.vm.info" value="mixed mode"/>
+ <property name="env.LOGNAME" value="blafond"/>
+ <property name="os.version" value="2.6.24-24-generic"/>
+ <property name="path.separator" value=":"/>
+ <property name="java.vm.version" value="14.0-b16"/>
+ <property name="java.awt.printerjob" value="sun.print.PSPrinterJob"/>
+ <property name="env.WINDOWPATH" value="7"/>
+ <property name="sun.io.unicode.encoding" value="UnicodeLittle"/>
+ <property name="env.GDM_LANG" value="en_US.UTF-8"/>
+ <property name="user.home" value="/home/blafond"/>
+ <property name="java.specification.vendor" value="Sun Microsystems Inc."/>
+ <property name="java.library.path" value="/usr/lib/jvm/java-6-sun-1.6.0.14/jre/lib/i386/server:/usr/lib/jvm/java-6-sun-1.6.0.14/jre/lib/i386:/usr/lib/jvm/java-6-sun-1.6.0.14/jre/../lib/i386:/usr/lib/jvm/java-6-openjdk/jre/lib/i386/client:/usr/lib/jvm/java-6-openjdk/jre/lib/i386:/usr/lib/xulrunner-addons:/usr/lib/xulrunner-addons:/usr/lib/xulrunner-addons:/usr/java/packages/lib/i386:/lib:/usr/lib"/>
+ <property name="java.vendor.url" value="http://java.sun.com/"/>
+ <property name="env.GDM_XSERVER_LOCATION" value="local"/>
+ <property name="java.vm.vendor" value="Sun Microsystems Inc."/>
+ <property name="maven.home" value="EMBEDDED"/>
+ <property name="java.runtime.name" value="Java(TM) SE Runtime Environment"/>
+ <property name="java.class.path" value="/home/blafond/Programs/eclipse-SDK-3.5/plugins/org.maven.ide.components.maven_embedder_2.1.0.20080530-2300/jars/plexus-classworlds-1.2-alpha-12.jar"/>
+ <property name="env.XFILESEARCHPATH" value="/usr/dt/app-defaults/%L/Dt"/>
+ <property name="java.vm.specification.name" value="Java Virtual Machine Specification"/>
+ <property name="java.vm.specification.version" value="1.0"/>
+ <property name="m2eclipse.workspace.state" value="/home/blafond/Workspaces/DNA/.metadata/.plugins/org.maven.ide.eclipse/workspacestate.properties"/>
+ <property name="sun.cpu.endian" value="little"/>
+ <property name="env.GTK_RC_FILES" value="/etc/gtk/gtkrc:/home/blafond/.gtkrc-1.2-gnome2"/>
+ <property name="sun.os.patch.level" value="unknown"/>
+ <property name="env.HOME" value="/home/blafond"/>
+ <property name="surefire.test.class.path" value="/home/blafond/Workspaces/DNA/dna/extensions/dna-sequencer-ddl/target/test-classes:/home/blafond/Workspaces/DNA/dna/extensions/dna-sequencer-ddl/target/classes:/home/blafond/.m2/repository/hsqldb/hsqldb/1.8.0.2/hsqldb-1.8.0.2.jar:/home/blafond/.m2/repository/org/jboss/dna/dna-common/0.7-SNAPSHOT/dna-common-0.7-SNAPSHOT.jar:/home/blafond/.m2/repository/org/slf4j/slf4j-api/1.5.8/slf4j-api-1.5.8.jar:/home/blafond/.m2/repository/net/jcip/jcip-annotations/1.0/jcip-annotations-1.0.jar:/home/blafond/.m2/repository/org/jboss/dna/dna-graph/0.7-SNAPSHOT/dna-graph-0.7-SNAPSHOT.jar:/home/blafond/.m2/repository/joda-time/joda-time/1.4/joda-time-1.4.jar:/home/blafond/.m2/repository/com/google/code/google-collections/google-collect/snapshot-20080530/google-collect-snapshot-20080530.jar:/home/blafond/.m2/repository/org/jboss/dna/dna-common/0.7-SNAPSHOT/dna-common-0.7-SNAPSHOT-tests.jar:/home/blafond/.m2/repository/org/jboss/dna/dna-graph/!
0.7-SNAPSHOT/dna-graph-0.7-SNAPSHOT-tests.jar:/home/blafond/.m2/repository/junit/junit/4.4/junit-4.4.jar:/home/blafond/.m2/repository/org/hamcrest/hamcrest-library/1.1/hamcrest-library-1.1.jar:/home/blafond/.m2/repository/org/hamcrest/hamcrest-core/1.1/hamcrest-core-1.1.jar:/home/blafond/.m2/repository/org/mockito/mockito-all/1.5/mockito-all-1.5.jar:/home/blafond/.m2/repository/org/slf4j/slf4j-log4j12/1.5.8/slf4j-log4j12-1.5.8.jar:/home/blafond/.m2/repository/log4j/log4j/1.2.14/log4j-1.2.14.jar:"/>
+ <property name="java.io.tmpdir" value="/home/blafond/Workspaces/DNA/dna/extensions/dna-sequencer-ddl/target"/>
+ <property name="env.LD_LIBRARY_PATH" value="/usr/lib/jvm/java-6-sun-1.6.0.14/jre/lib/i386/server:/usr/lib/jvm/java-6-sun-1.6.0.14/jre/lib/i386:/usr/lib/jvm/java-6-sun-1.6.0.14/jre/../lib/i386:/usr/lib/jvm/java-6-openjdk/jre/lib/i386/client:/usr/lib/jvm/java-6-openjdk/jre/lib/i386:/usr/lib/xulrunner-addons:/usr/lib/xulrunner-addons:/usr/lib/xulrunner-addons"/>
+ <property name="java.vendor.url.bug" value="http://java.sun.com/cgi-bin/bugreport.cgi"/>
+ <property name="env.SSH_AUTH_SOCK" value="/tmp/keyring-dF941n/ssh"/>
+ <property name="java.awt.graphicsenv" value="sun.awt.X11GraphicsEnvironment"/>
+ <property name="os.arch" value="i386"/>
+ <property name="java.ext.dirs" value="/usr/lib/jvm/java-6-sun-1.6.0.14/jre/lib/ext:/usr/java/packages/lib/ext"/>
+ <property name="user.dir" value="/home/blafond/Workspaces/DNA/dna/extensions/dna-sequencer-ddl"/>
+ <property name="env.XAUTHORITY" value="/home/blafond/.Xauthority"/>
+ <property name="line.separator" value="
+"/>
+ <property name="java.vm.name" value="Java HotSpot(TM) Server VM"/>
+ <property name="basedir" value="/home/blafond/Workspaces/DNA/dna/extensions/dna-sequencer-ddl"/>
+ <property name="maven.mode.standalone" value="true"/>
+ <property name="env.USERNAME" value="blafond"/>
+ <property name="file.encoding" value="UTF-8"/>
+ <property name="env.GNOME_KEYRING_SOCKET" value="/tmp/keyring-dF941n/socket"/>
+ <property name="env.GPG_AGENT_INFO" value="/tmp/seahorse-ZO5q59/S.gpg-agent:5994:1"/>
+ <property name="java.specification.version" value="1.6"/>
+ </properties>
+ <testcase time="0.024" classname="org.jboss.dna.sequencer.ddl.dialect.DerbyDdlParserTest" name="shouldParseDerbyTestDDL">
+ <error type="java.lang.NullPointerException">java.lang.NullPointerException
+ at org.jboss.dna.sequencer.ddl.dialect.DerbyDdlParserTest.getFileContent(DerbyDdlParserTest.java:50)
+ at org.jboss.dna.sequencer.ddl.dialect.DerbyDdlParserTest.shouldParseDerbyTestDDL(DerbyDdlParserTest.java:63)
+ at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
+ at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
+ at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
+ at java.lang.reflect.Method.invoke(Method.java:597)
+ at org.junit.internal.runners.TestMethod.invoke(TestMethod.java:59)
+ at org.junit.internal.runners.MethodRoadie.runTestMethod(MethodRoadie.java:98)
+ at org.junit.internal.runners.MethodRoadie$2.run(MethodRoadie.java:79)
+ at org.junit.internal.runners.MethodRoadie.runBeforesThenTestThenAfters(MethodRoadie.java:87)
+ at org.junit.internal.runners.MethodRoadie.runTest(MethodRoadie.java:77)
+ at org.junit.internal.runners.MethodRoadie.run(MethodRoadie.java:42)
+ at org.junit.internal.runners.JUnit4ClassRunner.invokeTestMethod(JUnit4ClassRunner.java:88)
+ at org.junit.internal.runners.JUnit4ClassRunner.runMethods(JUnit4ClassRunner.java:51)
+ at org.junit.internal.runners.JUnit4ClassRunner$1.run(JUnit4ClassRunner.java:44)
+ at org.junit.internal.runners.ClassRoadie.runUnprotected(ClassRoadie.java:27)
+ at org.junit.internal.runners.ClassRoadie.runProtected(ClassRoadie.java:37)
+ at org.junit.internal.runners.JUnit4ClassRunner.run(JUnit4ClassRunner.java:42)
+ at org.apache.maven.surefire.junit4.JUnit4TestSet.execute(JUnit4TestSet.java:62)
+ at org.apache.maven.surefire.suite.AbstractDirectoryTestSuite.executeTestSet(AbstractDirectoryTestSuite.java:140)
+ at org.apache.maven.surefire.suite.AbstractDirectoryTestSuite.execute(AbstractDirectoryTestSuite.java:127)
+ at org.apache.maven.surefire.Surefire.run(Surefire.java:177)
+ at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
+ at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
+ at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
+ at java.lang.reflect.Method.invoke(Method.java:597)
+ at org.apache.maven.surefire.booter.SurefireBooter.runSuitesInProcess(SurefireBooter.java:338)
+ at org.apache.maven.surefire.booter.SurefireBooter.main(SurefireBooter.java:997)
+</error>
+ <system-out> Getting Content for File = src/test/resources/ddl/derby_test_bugs.ddl
+java.io.FileNotFoundException: src/test/resources/ddl/derby_test_bugs.ddl (No such file or directory)</system-out>
+ </testcase>
+ <testcase time="2.171" classname="org.jboss.dna.sequencer.ddl.dialect.DerbyDdlParserTest" name="shouldParseDerbyDDL"/>
+</testsuite>
\ No newline at end of file
Property changes on: branches/ddl_sequencer/extensions/dna-sequencer-ddl/target/surefire-reports/TEST-org.jboss.dna.sequencer.ddl.dialect.DerbyDdlParserTest.xml
___________________________________________________________________
Name: svn:mime-type
+ text/plain
Added: branches/ddl_sequencer/extensions/dna-sequencer-ddl/target/surefire-reports/TEST-org.jboss.dna.sequencer.ddl.dialect.OracleDdlParserTest.xml
===================================================================
--- branches/ddl_sequencer/extensions/dna-sequencer-ddl/target/surefire-reports/TEST-org.jboss.dna.sequencer.ddl.dialect.OracleDdlParserTest.xml (rev 0)
+++ branches/ddl_sequencer/extensions/dna-sequencer-ddl/target/surefire-reports/TEST-org.jboss.dna.sequencer.ddl.dialect.OracleDdlParserTest.xml 2009-10-02 16:13:40 UTC (rev 1280)
@@ -0,0 +1,126 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<testsuite failures="0" time="0.517" errors="1" skipped="0" tests="1" name="org.jboss.dna.sequencer.ddl.dialect.OracleDdlParserTest">
+ <properties>
+ <property name="java.vendor" value="Sun Microsystems Inc."/>
+ <property name="env.SESSION_MANAGER" value="local/work-laptop:/tmp/.ICE-unix/5913"/>
+ <property name="localRepository" value="/home/blafond/.m2/repository"/>
+ <property name="sun.java.launcher" value="SUN_STANDARD"/>
+ <property name="sun.management.compiler" value="HotSpot Tiered Compilers"/>
+ <property name="os.name" value="Linux"/>
+ <property name="sun.boot.class.path" value="/usr/lib/jvm/java-6-sun-1.6.0.14/jre/lib/resources.jar:/usr/lib/jvm/java-6-sun-1.6.0.14/jre/lib/rt.jar:/usr/lib/jvm/java-6-sun-1.6.0.14/jre/lib/sunrsasign.jar:/usr/lib/jvm/java-6-sun-1.6.0.14/jre/lib/jsse.jar:/usr/lib/jvm/java-6-sun-1.6.0.14/jre/lib/jce.jar:/usr/lib/jvm/java-6-sun-1.6.0.14/jre/lib/charsets.jar:/usr/lib/jvm/java-6-sun-1.6.0.14/jre/classes"/>
+ <property name="env.PWD" value="/home/blafond"/>
+ <property name="env.XDG_SESSION_COOKIE" value="70bef359dccaf87f474bc0d7490f06a9-1253116029.282562-1962947517"/>
+ <property name="sun.desktop" value="gnome"/>
+ <property name="env.LANG" value="en_US.UTF-8"/>
+ <property name="java.vm.specification.vendor" value="Sun Microsystems Inc."/>
+ <property name="java.runtime.version" value="1.6.0_14-b08"/>
+ <property name="env.DISPLAY" value=":0.0"/>
+ <property name="user.name" value="blafond"/>
+ <property name="env.USER" value="blafond"/>
+ <property name="env.SHELL" value="/bin/bash"/>
+ <property name="env.MOZILLA_FIVE_HOME" value="/usr/lib/xulrunner-addons"/>
+ <property name="env.DESKTOP_SESSION" value="default"/>
+ <property name="env.XDG_DATA_DIRS" value="/usr/local/share/:/usr/share/:/usr/share/gdm/"/>
+ <property name="env.NLSPATH" value="/usr/dt/lib/nls/msg/%L/%N.cat"/>
+ <property name="env.PATH" value="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games"/>
+ <property name="user.language" value="en"/>
+ <property name="sun.boot.library.path" value="/usr/lib/jvm/java-6-sun-1.6.0.14/jre/lib/i386"/>
+ <property name="classworlds.conf" value="/home/blafond/Workspaces/DNA/.metadata/.plugins/org.maven.ide.eclipse/launches/m2conf7839333797857365463.tmp"/>
+ <property name="java.version" value="1.6.0_14"/>
+ <property name="user.timezone" value="US/Central"/>
+ <property name="env.DBUS_SESSION_BUS_ADDRESS" value="unix:abstract=/tmp/dbus-Cmyp7m4oLS,guid=f006087070ce2e1077eb8f884ab1087e"/>
+ <property name="sun.arch.data.model" value="32"/>
+ <property name="java.endorsed.dirs" value="/usr/lib/jvm/java-6-sun-1.6.0.14/jre/lib/endorsed"/>
+ <property name="sun.cpu.isalist" value=""/>
+ <property name="sun.jnu.encoding" value="UTF-8"/>
+ <property name="file.encoding.pkg" value="sun.io"/>
+ <property name="file.separator" value="/"/>
+ <property name="java.specification.name" value="Java Platform API Specification"/>
+ <property name="env.GNOME_DESKTOP_SESSION_ID" value="Default"/>
+ <property name="java.class.version" value="50.0"/>
+ <property name="env.GDMSESSION" value="default"/>
+ <property name="user.country" value="US"/>
+ <property name="env.GNOME_KEYRING_PID" value="5912"/>
+ <property name="java.home" value="/usr/lib/jvm/java-6-sun-1.6.0.14/jre"/>
+ <property name="java.vm.info" value="mixed mode"/>
+ <property name="env.LOGNAME" value="blafond"/>
+ <property name="os.version" value="2.6.24-24-generic"/>
+ <property name="path.separator" value=":"/>
+ <property name="java.vm.version" value="14.0-b16"/>
+ <property name="java.awt.printerjob" value="sun.print.PSPrinterJob"/>
+ <property name="env.WINDOWPATH" value="7"/>
+ <property name="sun.io.unicode.encoding" value="UnicodeLittle"/>
+ <property name="env.GDM_LANG" value="en_US.UTF-8"/>
+ <property name="user.home" value="/home/blafond"/>
+ <property name="java.specification.vendor" value="Sun Microsystems Inc."/>
+ <property name="java.library.path" value="/usr/lib/jvm/java-6-sun-1.6.0.14/jre/lib/i386/server:/usr/lib/jvm/java-6-sun-1.6.0.14/jre/lib/i386:/usr/lib/jvm/java-6-sun-1.6.0.14/jre/../lib/i386:/usr/lib/jvm/java-6-openjdk/jre/lib/i386/client:/usr/lib/jvm/java-6-openjdk/jre/lib/i386:/usr/lib/xulrunner-addons:/usr/lib/xulrunner-addons:/usr/lib/xulrunner-addons:/usr/java/packages/lib/i386:/lib:/usr/lib"/>
+ <property name="java.vendor.url" value="http://java.sun.com/"/>
+ <property name="env.GDM_XSERVER_LOCATION" value="local"/>
+ <property name="java.vm.vendor" value="Sun Microsystems Inc."/>
+ <property name="maven.home" value="EMBEDDED"/>
+ <property name="java.runtime.name" value="Java(TM) SE Runtime Environment"/>
+ <property name="java.class.path" value="/home/blafond/Programs/eclipse-SDK-3.5/plugins/org.maven.ide.components.maven_embedder_2.1.0.20080530-2300/jars/plexus-classworlds-1.2-alpha-12.jar"/>
+ <property name="env.XFILESEARCHPATH" value="/usr/dt/app-defaults/%L/Dt"/>
+ <property name="java.vm.specification.name" value="Java Virtual Machine Specification"/>
+ <property name="java.vm.specification.version" value="1.0"/>
+ <property name="m2eclipse.workspace.state" value="/home/blafond/Workspaces/DNA/.metadata/.plugins/org.maven.ide.eclipse/workspacestate.properties"/>
+ <property name="sun.cpu.endian" value="little"/>
+ <property name="env.GTK_RC_FILES" value="/etc/gtk/gtkrc:/home/blafond/.gtkrc-1.2-gnome2"/>
+ <property name="sun.os.patch.level" value="unknown"/>
+ <property name="env.HOME" value="/home/blafond"/>
+ <property name="surefire.test.class.path" value="/home/blafond/Workspaces/DNA/dna/extensions/dna-sequencer-ddl/target/test-classes:/home/blafond/Workspaces/DNA/dna/extensions/dna-sequencer-ddl/target/classes:/home/blafond/.m2/repository/hsqldb/hsqldb/1.8.0.2/hsqldb-1.8.0.2.jar:/home/blafond/.m2/repository/org/jboss/dna/dna-common/0.7-SNAPSHOT/dna-common-0.7-SNAPSHOT.jar:/home/blafond/.m2/repository/org/slf4j/slf4j-api/1.5.8/slf4j-api-1.5.8.jar:/home/blafond/.m2/repository/net/jcip/jcip-annotations/1.0/jcip-annotations-1.0.jar:/home/blafond/.m2/repository/org/jboss/dna/dna-graph/0.7-SNAPSHOT/dna-graph-0.7-SNAPSHOT.jar:/home/blafond/.m2/repository/joda-time/joda-time/1.4/joda-time-1.4.jar:/home/blafond/.m2/repository/com/google/code/google-collections/google-collect/snapshot-20080530/google-collect-snapshot-20080530.jar:/home/blafond/.m2/repository/org/jboss/dna/dna-common/0.7-SNAPSHOT/dna-common-0.7-SNAPSHOT-tests.jar:/home/blafond/.m2/repository/org/jboss/dna/dna-graph/!
0.7-SNAPSHOT/dna-graph-0.7-SNAPSHOT-tests.jar:/home/blafond/.m2/repository/junit/junit/4.4/junit-4.4.jar:/home/blafond/.m2/repository/org/hamcrest/hamcrest-library/1.1/hamcrest-library-1.1.jar:/home/blafond/.m2/repository/org/hamcrest/hamcrest-core/1.1/hamcrest-core-1.1.jar:/home/blafond/.m2/repository/org/mockito/mockito-all/1.5/mockito-all-1.5.jar:/home/blafond/.m2/repository/org/slf4j/slf4j-log4j12/1.5.8/slf4j-log4j12-1.5.8.jar:/home/blafond/.m2/repository/log4j/log4j/1.2.14/log4j-1.2.14.jar:"/>
+ <property name="java.io.tmpdir" value="/home/blafond/Workspaces/DNA/dna/extensions/dna-sequencer-ddl/target"/>
+ <property name="env.LD_LIBRARY_PATH" value="/usr/lib/jvm/java-6-sun-1.6.0.14/jre/lib/i386/server:/usr/lib/jvm/java-6-sun-1.6.0.14/jre/lib/i386:/usr/lib/jvm/java-6-sun-1.6.0.14/jre/../lib/i386:/usr/lib/jvm/java-6-openjdk/jre/lib/i386/client:/usr/lib/jvm/java-6-openjdk/jre/lib/i386:/usr/lib/xulrunner-addons:/usr/lib/xulrunner-addons:/usr/lib/xulrunner-addons"/>
+ <property name="java.vendor.url.bug" value="http://java.sun.com/cgi-bin/bugreport.cgi"/>
+ <property name="env.SSH_AUTH_SOCK" value="/tmp/keyring-dF941n/ssh"/>
+ <property name="java.awt.graphicsenv" value="sun.awt.X11GraphicsEnvironment"/>
+ <property name="os.arch" value="i386"/>
+ <property name="java.ext.dirs" value="/usr/lib/jvm/java-6-sun-1.6.0.14/jre/lib/ext:/usr/java/packages/lib/ext"/>
+ <property name="user.dir" value="/home/blafond/Workspaces/DNA/dna/extensions/dna-sequencer-ddl"/>
+ <property name="env.XAUTHORITY" value="/home/blafond/.Xauthority"/>
+ <property name="line.separator" value="
+"/>
+ <property name="java.vm.name" value="Java HotSpot(TM) Server VM"/>
+ <property name="basedir" value="/home/blafond/Workspaces/DNA/dna/extensions/dna-sequencer-ddl"/>
+ <property name="maven.mode.standalone" value="true"/>
+ <property name="env.USERNAME" value="blafond"/>
+ <property name="file.encoding" value="UTF-8"/>
+ <property name="env.GNOME_KEYRING_SOCKET" value="/tmp/keyring-dF941n/socket"/>
+ <property name="env.GPG_AGENT_INFO" value="/tmp/seahorse-ZO5q59/S.gpg-agent:5994:1"/>
+ <property name="java.specification.version" value="1.6"/>
+ </properties>
+ <testcase time="0.514" classname="org.jboss.dna.sequencer.ddl.dialect.OracleDdlParserTest" name="shouldParseGFM_PhysicalDDL">
+ <error type="java.lang.NullPointerException">java.lang.NullPointerException
+ at org.jboss.dna.sequencer.ddl.dialect.OracleDdlParserTest.getFileContent(OracleDdlParserTest.java:50)
+ at org.jboss.dna.sequencer.ddl.dialect.OracleDdlParserTest.shouldParseGFM_PhysicalDDL(OracleDdlParserTest.java:83)
+ at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
+ at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
+ at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
+ at java.lang.reflect.Method.invoke(Method.java:597)
+ at org.junit.internal.runners.TestMethod.invoke(TestMethod.java:59)
+ at org.junit.internal.runners.MethodRoadie.runTestMethod(MethodRoadie.java:98)
+ at org.junit.internal.runners.MethodRoadie$2.run(MethodRoadie.java:79)
+ at org.junit.internal.runners.MethodRoadie.runBeforesThenTestThenAfters(MethodRoadie.java:87)
+ at org.junit.internal.runners.MethodRoadie.runTest(MethodRoadie.java:77)
+ at org.junit.internal.runners.MethodRoadie.run(MethodRoadie.java:42)
+ at org.junit.internal.runners.JUnit4ClassRunner.invokeTestMethod(JUnit4ClassRunner.java:88)
+ at org.junit.internal.runners.JUnit4ClassRunner.runMethods(JUnit4ClassRunner.java:51)
+ at org.junit.internal.runners.JUnit4ClassRunner$1.run(JUnit4ClassRunner.java:44)
+ at org.junit.internal.runners.ClassRoadie.runUnprotected(ClassRoadie.java:27)
+ at org.junit.internal.runners.ClassRoadie.runProtected(ClassRoadie.java:37)
+ at org.junit.internal.runners.JUnit4ClassRunner.run(JUnit4ClassRunner.java:42)
+ at org.apache.maven.surefire.junit4.JUnit4TestSet.execute(JUnit4TestSet.java:62)
+ at org.apache.maven.surefire.suite.AbstractDirectoryTestSuite.executeTestSet(AbstractDirectoryTestSuite.java:140)
+ at org.apache.maven.surefire.suite.AbstractDirectoryTestSuite.execute(AbstractDirectoryTestSuite.java:127)
+ at org.apache.maven.surefire.Surefire.run(Surefire.java:177)
+ at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
+ at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
+ at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
+ at java.lang.reflect.Method.invoke(Method.java:597)
+ at org.apache.maven.surefire.booter.SurefireBooter.runSuitesInProcess(SurefireBooter.java:338)
+ at org.apache.maven.surefire.booter.SurefireBooter.main(SurefireBooter.java:997)
+</error>
+ <system-out> Getting Content for File = src/test/resources/ddl/GFM_Physical.ddl
+java.io.FileNotFoundException: src/test/resources/ddl/GFM_Physical.ddl (No such file or directory)</system-out>
+ </testcase>
+</testsuite>
\ No newline at end of file
Property changes on: branches/ddl_sequencer/extensions/dna-sequencer-ddl/target/surefire-reports/TEST-org.jboss.dna.sequencer.ddl.dialect.OracleDdlParserTest.xml
___________________________________________________________________
Name: svn:mime-type
+ text/plain
Added: branches/ddl_sequencer/extensions/dna-sequencer-ddl/target/surefire-reports/org.jboss.dna.sequencer.ddl.BasicDdlParserTest.txt
===================================================================
--- branches/ddl_sequencer/extensions/dna-sequencer-ddl/target/surefire-reports/org.jboss.dna.sequencer.ddl.BasicDdlParserTest.txt (rev 0)
+++ branches/ddl_sequencer/extensions/dna-sequencer-ddl/target/surefire-reports/org.jboss.dna.sequencer.ddl.BasicDdlParserTest.txt 2009-10-02 16:13:40 UTC (rev 1280)
@@ -0,0 +1,35 @@
+-------------------------------------------------------------------------------
+Test set: org.jboss.dna.sequencer.ddl.BasicDdlParserTest
+-------------------------------------------------------------------------------
+Tests run: 5, Failures: 0, Errors: 1, Skipped: 0, Time elapsed: 0.166 sec <<< FAILURE!
+shouldParseCreateTables(org.jboss.dna.sequencer.ddl.BasicDdlParserTest) Time elapsed: 0.023 sec <<< ERROR!
+java.lang.NullPointerException
+ at org.jboss.dna.sequencer.ddl.BasicDdlParserTest.getFileContent(BasicDdlParserTest.java:59)
+ at org.jboss.dna.sequencer.ddl.BasicDdlParserTest.shouldParseCreateTables(BasicDdlParserTest.java:159)
+ at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
+ at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
+ at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
+ at java.lang.reflect.Method.invoke(Method.java:597)
+ at org.junit.internal.runners.TestMethod.invoke(TestMethod.java:59)
+ at org.junit.internal.runners.MethodRoadie.runTestMethod(MethodRoadie.java:98)
+ at org.junit.internal.runners.MethodRoadie$2.run(MethodRoadie.java:79)
+ at org.junit.internal.runners.MethodRoadie.runBeforesThenTestThenAfters(MethodRoadie.java:87)
+ at org.junit.internal.runners.MethodRoadie.runTest(MethodRoadie.java:77)
+ at org.junit.internal.runners.MethodRoadie.run(MethodRoadie.java:42)
+ at org.junit.internal.runners.JUnit4ClassRunner.invokeTestMethod(JUnit4ClassRunner.java:88)
+ at org.junit.internal.runners.JUnit4ClassRunner.runMethods(JUnit4ClassRunner.java:51)
+ at org.junit.internal.runners.JUnit4ClassRunner$1.run(JUnit4ClassRunner.java:44)
+ at org.junit.internal.runners.ClassRoadie.runUnprotected(ClassRoadie.java:27)
+ at org.junit.internal.runners.ClassRoadie.runProtected(ClassRoadie.java:37)
+ at org.junit.internal.runners.JUnit4ClassRunner.run(JUnit4ClassRunner.java:42)
+ at org.apache.maven.surefire.junit4.JUnit4TestSet.execute(JUnit4TestSet.java:62)
+ at org.apache.maven.surefire.suite.AbstractDirectoryTestSuite.executeTestSet(AbstractDirectoryTestSuite.java:140)
+ at org.apache.maven.surefire.suite.AbstractDirectoryTestSuite.execute(AbstractDirectoryTestSuite.java:127)
+ at org.apache.maven.surefire.Surefire.run(Surefire.java:177)
+ at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
+ at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
+ at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
+ at java.lang.reflect.Method.invoke(Method.java:597)
+ at org.apache.maven.surefire.booter.SurefireBooter.runSuitesInProcess(SurefireBooter.java:338)
+ at org.apache.maven.surefire.booter.SurefireBooter.main(SurefireBooter.java:997)
+
Property changes on: branches/ddl_sequencer/extensions/dna-sequencer-ddl/target/surefire-reports/org.jboss.dna.sequencer.ddl.BasicDdlParserTest.txt
___________________________________________________________________
Name: svn:mime-type
+ text/plain
Added: branches/ddl_sequencer/extensions/dna-sequencer-ddl/target/surefire-reports/org.jboss.dna.sequencer.ddl.datatype.DataTypeParserTest.txt
===================================================================
--- branches/ddl_sequencer/extensions/dna-sequencer-ddl/target/surefire-reports/org.jboss.dna.sequencer.ddl.datatype.DataTypeParserTest.txt (rev 0)
+++ branches/ddl_sequencer/extensions/dna-sequencer-ddl/target/surefire-reports/org.jboss.dna.sequencer.ddl.datatype.DataTypeParserTest.txt 2009-10-02 16:13:40 UTC (rev 1280)
@@ -0,0 +1,4 @@
+-------------------------------------------------------------------------------
+Test set: org.jboss.dna.sequencer.ddl.datatype.DataTypeParserTest
+-------------------------------------------------------------------------------
+Tests run: 28, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.286 sec
Property changes on: branches/ddl_sequencer/extensions/dna-sequencer-ddl/target/surefire-reports/org.jboss.dna.sequencer.ddl.datatype.DataTypeParserTest.txt
___________________________________________________________________
Name: svn:mime-type
+ text/plain
Added: branches/ddl_sequencer/extensions/dna-sequencer-ddl/target/surefire-reports/org.jboss.dna.sequencer.ddl.dialect.DerbyDdlParserTest.txt
===================================================================
--- branches/ddl_sequencer/extensions/dna-sequencer-ddl/target/surefire-reports/org.jboss.dna.sequencer.ddl.dialect.DerbyDdlParserTest.txt (rev 0)
+++ branches/ddl_sequencer/extensions/dna-sequencer-ddl/target/surefire-reports/org.jboss.dna.sequencer.ddl.dialect.DerbyDdlParserTest.txt 2009-10-02 16:13:40 UTC (rev 1280)
@@ -0,0 +1,35 @@
+-------------------------------------------------------------------------------
+Test set: org.jboss.dna.sequencer.ddl.dialect.DerbyDdlParserTest
+-------------------------------------------------------------------------------
+Tests run: 2, Failures: 0, Errors: 1, Skipped: 0, Time elapsed: 2.2 sec <<< FAILURE!
+shouldParseDerbyTestDDL(org.jboss.dna.sequencer.ddl.dialect.DerbyDdlParserTest) Time elapsed: 0.024 sec <<< ERROR!
+java.lang.NullPointerException
+ at org.jboss.dna.sequencer.ddl.dialect.DerbyDdlParserTest.getFileContent(DerbyDdlParserTest.java:50)
+ at org.jboss.dna.sequencer.ddl.dialect.DerbyDdlParserTest.shouldParseDerbyTestDDL(DerbyDdlParserTest.java:63)
+ at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
+ at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
+ at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
+ at java.lang.reflect.Method.invoke(Method.java:597)
+ at org.junit.internal.runners.TestMethod.invoke(TestMethod.java:59)
+ at org.junit.internal.runners.MethodRoadie.runTestMethod(MethodRoadie.java:98)
+ at org.junit.internal.runners.MethodRoadie$2.run(MethodRoadie.java:79)
+ at org.junit.internal.runners.MethodRoadie.runBeforesThenTestThenAfters(MethodRoadie.java:87)
+ at org.junit.internal.runners.MethodRoadie.runTest(MethodRoadie.java:77)
+ at org.junit.internal.runners.MethodRoadie.run(MethodRoadie.java:42)
+ at org.junit.internal.runners.JUnit4ClassRunner.invokeTestMethod(JUnit4ClassRunner.java:88)
+ at org.junit.internal.runners.JUnit4ClassRunner.runMethods(JUnit4ClassRunner.java:51)
+ at org.junit.internal.runners.JUnit4ClassRunner$1.run(JUnit4ClassRunner.java:44)
+ at org.junit.internal.runners.ClassRoadie.runUnprotected(ClassRoadie.java:27)
+ at org.junit.internal.runners.ClassRoadie.runProtected(ClassRoadie.java:37)
+ at org.junit.internal.runners.JUnit4ClassRunner.run(JUnit4ClassRunner.java:42)
+ at org.apache.maven.surefire.junit4.JUnit4TestSet.execute(JUnit4TestSet.java:62)
+ at org.apache.maven.surefire.suite.AbstractDirectoryTestSuite.executeTestSet(AbstractDirectoryTestSuite.java:140)
+ at org.apache.maven.surefire.suite.AbstractDirectoryTestSuite.execute(AbstractDirectoryTestSuite.java:127)
+ at org.apache.maven.surefire.Surefire.run(Surefire.java:177)
+ at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
+ at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
+ at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
+ at java.lang.reflect.Method.invoke(Method.java:597)
+ at org.apache.maven.surefire.booter.SurefireBooter.runSuitesInProcess(SurefireBooter.java:338)
+ at org.apache.maven.surefire.booter.SurefireBooter.main(SurefireBooter.java:997)
+
Property changes on: branches/ddl_sequencer/extensions/dna-sequencer-ddl/target/surefire-reports/org.jboss.dna.sequencer.ddl.dialect.DerbyDdlParserTest.txt
___________________________________________________________________
Name: svn:mime-type
+ text/plain
Added: branches/ddl_sequencer/extensions/dna-sequencer-ddl/target/surefire-reports/org.jboss.dna.sequencer.ddl.dialect.OracleDdlParserTest.txt
===================================================================
--- branches/ddl_sequencer/extensions/dna-sequencer-ddl/target/surefire-reports/org.jboss.dna.sequencer.ddl.dialect.OracleDdlParserTest.txt (rev 0)
+++ branches/ddl_sequencer/extensions/dna-sequencer-ddl/target/surefire-reports/org.jboss.dna.sequencer.ddl.dialect.OracleDdlParserTest.txt 2009-10-02 16:13:40 UTC (rev 1280)
@@ -0,0 +1,35 @@
+-------------------------------------------------------------------------------
+Test set: org.jboss.dna.sequencer.ddl.dialect.OracleDdlParserTest
+-------------------------------------------------------------------------------
+Tests run: 1, Failures: 0, Errors: 1, Skipped: 0, Time elapsed: 0.534 sec <<< FAILURE!
+shouldParseGFM_PhysicalDDL(org.jboss.dna.sequencer.ddl.dialect.OracleDdlParserTest) Time elapsed: 0.515 sec <<< ERROR!
+java.lang.NullPointerException
+ at org.jboss.dna.sequencer.ddl.dialect.OracleDdlParserTest.getFileContent(OracleDdlParserTest.java:50)
+ at org.jboss.dna.sequencer.ddl.dialect.OracleDdlParserTest.shouldParseGFM_PhysicalDDL(OracleDdlParserTest.java:83)
+ at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
+ at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
+ at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
+ at java.lang.reflect.Method.invoke(Method.java:597)
+ at org.junit.internal.runners.TestMethod.invoke(TestMethod.java:59)
+ at org.junit.internal.runners.MethodRoadie.runTestMethod(MethodRoadie.java:98)
+ at org.junit.internal.runners.MethodRoadie$2.run(MethodRoadie.java:79)
+ at org.junit.internal.runners.MethodRoadie.runBeforesThenTestThenAfters(MethodRoadie.java:87)
+ at org.junit.internal.runners.MethodRoadie.runTest(MethodRoadie.java:77)
+ at org.junit.internal.runners.MethodRoadie.run(MethodRoadie.java:42)
+ at org.junit.internal.runners.JUnit4ClassRunner.invokeTestMethod(JUnit4ClassRunner.java:88)
+ at org.junit.internal.runners.JUnit4ClassRunner.runMethods(JUnit4ClassRunner.java:51)
+ at org.junit.internal.runners.JUnit4ClassRunner$1.run(JUnit4ClassRunner.java:44)
+ at org.junit.internal.runners.ClassRoadie.runUnprotected(ClassRoadie.java:27)
+ at org.junit.internal.runners.ClassRoadie.runProtected(ClassRoadie.java:37)
+ at org.junit.internal.runners.JUnit4ClassRunner.run(JUnit4ClassRunner.java:42)
+ at org.apache.maven.surefire.junit4.JUnit4TestSet.execute(JUnit4TestSet.java:62)
+ at org.apache.maven.surefire.suite.AbstractDirectoryTestSuite.executeTestSet(AbstractDirectoryTestSuite.java:140)
+ at org.apache.maven.surefire.suite.AbstractDirectoryTestSuite.execute(AbstractDirectoryTestSuite.java:127)
+ at org.apache.maven.surefire.Surefire.run(Surefire.java:177)
+ at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
+ at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
+ at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
+ at java.lang.reflect.Method.invoke(Method.java:597)
+ at org.apache.maven.surefire.booter.SurefireBooter.runSuitesInProcess(SurefireBooter.java:338)
+ at org.apache.maven.surefire.booter.SurefireBooter.main(SurefireBooter.java:997)
+
Property changes on: branches/ddl_sequencer/extensions/dna-sequencer-ddl/target/surefire-reports/org.jboss.dna.sequencer.ddl.dialect.OracleDdlParserTest.txt
___________________________________________________________________
Name: svn:mime-type
+ text/plain
Added: branches/ddl_sequencer/extensions/dna-sequencer-ddl/target/test-classes/org/jboss/dna/sequencer/ddl/datatype/DataTypeParserTest.class
===================================================================
(Binary files differ)
Property changes on: branches/ddl_sequencer/extensions/dna-sequencer-ddl/target/test-classes/org/jboss/dna/sequencer/ddl/datatype/DataTypeParserTest.class
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: branches/ddl_sequencer/extensions/dna-sequencer-ddl/target/test-classes/org/jboss/dna/sequencer/ddl/dialect/DerbyDdlParserTest.class
===================================================================
(Binary files differ)
Property changes on: branches/ddl_sequencer/extensions/dna-sequencer-ddl/target/test-classes/org/jboss/dna/sequencer/ddl/dialect/DerbyDdlParserTest.class
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: branches/ddl_sequencer/extensions/dna-sequencer-ddl/target/test-classes/org/jboss/dna/sequencer/ddl/dialect/OracleDdlParserTest.class
===================================================================
(Binary files differ)
Property changes on: branches/ddl_sequencer/extensions/dna-sequencer-ddl/target/test-classes/org/jboss/dna/sequencer/ddl/dialect/OracleDdlParserTest.class
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: branches/ddl_sequencer/extensions/dna-sequencer-ddl/target/test-classes/sql2bnf.aug92.txt
===================================================================
--- branches/ddl_sequencer/extensions/dna-sequencer-ddl/target/test-classes/sql2bnf.aug92.txt (rev 0)
+++ branches/ddl_sequencer/extensions/dna-sequencer-ddl/target/test-classes/sql2bnf.aug92.txt 2009-10-02 16:13:40 UTC (rev 1280)
@@ -0,0 +1,2594 @@
+This file contains a depth-first tree traversal of the BNF
+for the language done at about 27-AUG-1992 11:03:41.64.
+The specific version of the BNF included here is: ANSI-only, SQL2-only.
+
+
+<SQL terminal character> ::=
+ <SQL language character>
+ | <SQL embedded language character>
+
+<SQL language character> ::=
+ <simple Latin letter>
+ | <digit>
+ | <SQL special character>
+
+<simple Latin letter> ::=
+ <simple Latin upper case letter>
+ | <simple Latin lower case letter>
+
+<simple Latin upper case letter> ::=
+ A | B | C | D | E | F | G | H | I | J | K | L | M | N | O
+ | P | Q | R | S | T | U | V | W | X | Y | Z
+
+<simple Latin lower case letter> ::=
+ a | b | c | d | e | f | g | h | i | j | k | l | m | n | o
+ | p | q | r | s | t | u | v | w | x | y | z
+
+<digit> ::=
+ 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9
+
+<SQL special character> ::=
+ <space>
+ | <double quote>
+ | <percent>
+ | <ampersand>
+ | <quote>
+ | <left paren>
+ | <right paren>
+ | <asterisk>
+ | <plus sign>
+ | <comma>
+ | <minus sign>
+ | <period>
+ | <solidus>
+ | <colon>
+ | <semicolon>
+ | <less than operator>
+ | <equals operator>
+ | <greater than operator>
+ | <question mark>
+ | <underscore>
+ | <vertical bar>
+
+<space> ::= !! <EMPHASIS>(space character in character set in use)
+
+<double quote> ::= "
+
+<percent> ::= %
+
+<ampersand> ::= &
+
+<quote> ::= '
+
+<left paren> ::= (
+
+<right paren> ::= )
+
+<asterisk> ::= *
+
+<plus sign> ::= +
+
+<comma> ::= ,
+
+<minus sign> ::= -
+
+<period> ::= .
+
+<solidus> ::= /
+
+<colon> ::= :
+
+<semicolon> ::= ;
+
+<less than operator> ::= <
+
+<equals operator> ::= =
+
+<greater than operator> ::= >
+
+<question mark> ::= ?
+
+<underscore> ::= _
+
+<vertical bar> ::= |
+
+<SQL embedded language character> ::=
+ <left bracket>
+ | <right bracket>
+
+<left bracket> ::= [
+
+<right bracket> ::= ]
+
+<token> ::=
+ <nondelimiter token>
+ | <delimiter token>
+
+<nondelimiter token> ::=
+ <regular identifier>
+ | <key word>
+ | <unsigned numeric literal>
+ | <national character string literal>
+ | <bit string literal>
+ | <hex string literal>
+
+<regular identifier> ::= <identifier body>
+
+<identifier body> ::=
+ <identifier start> [ { <underscore> | <identifier part> }... ]
+
+<identifier start> ::= <EMPHASIS>(!! See the Syntax Rules)
+
+<identifier part> ::=
+ <identifier start>
+ | <digit>
+
+<key word> ::=
+ <reserved word>
+ | <non-reserved word>
+
+<reserved word> ::=
+ ABSOLUTE | ACTION | ADD | ALL
+ | ALLOCATE | ALTER | AND
+ | ANY | ARE
+ | AS | ASC
+ | ASSERTION | AT
+ | AUTHORIZATION | AVG
+ | BEGIN | BETWEEN | BIT | BIT_LENGTH
+ | BOTH | BY
+ | CASCADE | CASCADED | CASE | CAST
+ | CATALOG
+ | CHAR | CHARACTER | CHAR_LENGTH
+ | CHARACTER_LENGTH | CHECK | CLOSE | COALESCE
+ | COLLATE | COLLATION
+ | COLUMN | COMMIT
+ | CONNECT
+ | CONNECTION | CONSTRAINT
+ | CONSTRAINTS | CONTINUE
+ | CONVERT | CORRESPONDING | COUNT | CREATE | CROSS
+ | CURRENT
+ | CURRENT_DATE | CURRENT_TIME
+ | CURRENT_TIMESTAMP | CURRENT_USER | CURSOR
+ | DATE | DAY | DEALLOCATE | DEC
+ | DECIMAL | DECLARE | DEFAULT | DEFERRABLE
+ | DEFERRED | DELETE | DESC | DESCRIBE | DESCRIPTOR
+ | DIAGNOSTICS
+ | DISCONNECT | DISTINCT | DOMAIN | DOUBLE | DROP
+ | ELSE | END | END-EXEC | ESCAPE
+ | EXCEPT | EXCEPTION
+ | EXEC | EXECUTE | EXISTS
+ | EXTERNAL | EXTRACT
+ | FALSE | FETCH | FIRST | FLOAT | FOR
+ | FOREIGN | FOUND | FROM | FULL
+ | GET | GLOBAL | GO | GOTO
+ | GRANT | GROUP
+ | HAVING | HOUR
+ | IDENTITY | IMMEDIATE | IN | INDICATOR
+ | INITIALLY | INNER | INPUT
+ | INSENSITIVE | INSERT | INT | INTEGER | INTERSECT
+ | INTERVAL | INTO | IS
+ | ISOLATION
+ | JOIN
+ | KEY
+ | LANGUAGE | LAST | LEADING | LEFT
+ | LEVEL | LIKE | LOCAL | LOWER
+ | MATCH | MAX | MIN | MINUTE | MODULE
+ | MONTH
+ | NAMES | NATIONAL | NATURAL | NCHAR | NEXT | NO
+ | NOT | NULL
+ | NULLIF | NUMERIC
+ | OCTET_LENGTH | OF
+ | ON | ONLY | OPEN | OPTION | OR
+ | ORDER | OUTER
+ | OUTPUT | OVERLAPS
+ | PAD | PARTIAL | POSITION | PRECISION | PREPARE
+ | PRESERVE | PRIMARY
+ | PRIOR | PRIVILEGES | PROCEDURE | PUBLIC
+ | READ | REAL | REFERENCES | RELATIVE | RESTRICT
+ | REVOKE | RIGHT
+ | ROLLBACK | ROWS
+ | SCHEMA | SCROLL | SECOND | SECTION
+ | SELECT
+ | SESSION | SESSION_USER | SET
+ | SIZE | SMALLINT | SOME | SPACE | SQL | SQLCODE
+ | SQLERROR | SQLSTATE
+ | SUBSTRING | SUM | SYSTEM_USER
+ | TABLE | TEMPORARY
+ | THEN | TIME | TIMESTAMP
+ | TIMEZONE_HOUR | TIMEZONE_MINUTE
+ | TO | TRAILING | TRANSACTION
+ | TRANSLATE | TRANSLATION | TRIM | TRUE
+ | UNION | UNIQUE | UNKNOWN | UPDATE | UPPER | USAGE
+ | USER | USING
+ | VALUE | VALUES | VARCHAR | VARYING | VIEW
+ | WHEN | WHENEVER | WHERE | WITH | WORK | WRITE
+ | YEAR
+ | ZONE
+
+<non-reserved word> ::=
+
+ ADA
+ | C | CATALOG_NAME
+ | CHARACTER_SET_CATALOG | CHARACTER_SET_NAME
+ | CHARACTER_SET_SCHEMA | CLASS_ORIGIN | COBOL | COLLATION_CATALOG
+ | COLLATION_NAME | COLLATION_SCHEMA | COLUMN_NAME | COMMAND_FUNCTION
+ | COMMITTED
+ | CONDITION_NUMBER | CONNECTION_NAME | CONSTRAINT_CATALOG | CONSTRAINT_NAME
+ | CONSTRAINT_SCHEMA | CURSOR_NAME
+ | DATA | DATETIME_INTERVAL_CODE
+ | DATETIME_INTERVAL_PRECISION | DYNAMIC_FUNCTION
+ | FORTRAN
+ | LENGTH
+ | MESSAGE_LENGTH | MESSAGE_OCTET_LENGTH | MESSAGE_TEXT | MORE | MUMPS
+ | NAME | NULLABLE | NUMBER
+ | PASCAL | PLI
+ | REPEATABLE | RETURNED_LENGTH | RETURNED_OCTET_LENGTH | RETURNED_SQLSTATE
+ | ROW_COUNT
+ | SCALE | SCHEMA_NAME | SERIALIZABLE | SERVER_NAME | SUBCLASS_ORIGIN
+ | TABLE_NAME | TYPE
+ | UNCOMMITTED | UNNAMED
+
+<unsigned numeric literal> ::=
+ <exact numeric literal>
+ | <approximate numeric literal>
+
+<exact numeric literal> ::=
+ <unsigned integer> [ <period> [ <unsigned integer> ] ]
+ | <period> <unsigned integer>
+
+<unsigned integer> ::= <digit>...
+
+<approximate numeric literal> ::= <mantissa> E <exponent>
+
+<mantissa> ::= <exact numeric literal>
+
+<exponent> ::= <signed integer>
+
+<signed integer> ::= [ <sign> ] <unsigned integer>
+
+<sign> ::= <plus sign> | <minus sign>
+
+<national character string literal> ::=
+ N <quote> [ <character representation>... ] <quote>
+ [ { <separator>... <quote> [ <character representation>... ] <quote> }... ]
+
+<character representation> ::=
+ <nonquote character>
+ | <quote symbol>
+
+<nonquote character> ::= !! <EMPHASIS>(See the Syntax Rules.)
+
+<quote symbol> ::= <quote><quote>
+
+<separator> ::= { <comment> | <space> | <newline> }...
+
+<comment> ::=
+ <comment introducer> [ <comment character>... ] <newline>
+
+<comment introducer> ::= <minus sign><minus sign>[<minus sign>...]
+
+<comment character> ::=
+ <nonquote character>
+ | <quote>
+
+<newline> ::= !! <EMPHASIS>(implementation-defined end-of-line indicator)
+
+<bit string literal> ::=
+ B <quote> [ <bit>... ] <quote>
+ [ { <separator>... <quote> [ <bit>... ] <quote> }... ]
+
+<bit> ::= 0 | 1
+
+<hex string literal> ::=
+ X <quote> [ <hexit>... ] <quote>
+ [ { <separator>... <quote> [ <hexit>... ] <quote> }... ]
+
+<hexit> ::= <digit> | A | B | C | D | E | F | a | b | c | d | e | f
+
+<delimiter token> ::=
+ <character string literal>
+ | <date string>
+ | <time string>
+ | <timestamp string>
+ | <interval string>
+ | <delimited identifier>
+ | <SQL special character>
+ | <not equals operator>
+ | <greater than or equals operator>
+ | <less than or equals operator>
+ | <concatenation operator>
+ | <double period>
+ | <left bracket>
+ | <right bracket>
+
+<character string literal> ::=
+ [ <introducer><character set specification> ]
+ <quote> [ <character representation>... ] <quote>
+ [ { <separator>... <quote> [ <character representation>... ] <quote> }... ]
+
+<introducer> ::= <underscore>
+
+<character set specification> ::=
+ <standard character repertoire name>
+ | <implementation-defined character repertoire name>
+ | <user-defined character repertoire name>
+ | <standard universal character form-of-use name>
+ | <implementation-defined universal character form-of-use name>
+
+<standard character repertoire name> ::= <character set name>
+
+<character set name> ::= [ <schema name> <period> ]
+ <SQL language identifier>
+
+<schema name> ::=
+ [ <catalog name> <period> ] <unqualified schema name>
+
+<catalog name> ::= <identifier>
+
+<identifier> ::=
+ [ <introducer><character set specification> ] <actual identifier>
+
+<actual identifier> ::=
+ <regular identifier>
+ | <delimited identifier>
+
+<delimited identifier> ::=
+ <double quote> <delimited identifier body> <double quote>
+
+<delimited identifier body> ::= <delimited identifier part>...
+
+<delimited identifier part> ::=
+ <nondoublequote character>
+ | <doublequote symbol>
+
+<nondoublequote character> ::= <EMPHASIS>(!! See the Syntax Rules)
+
+<doublequote symbol> ::= <double quote><double quote>
+
+<unqualified schema name> ::= <identifier>
+
+<SQL language identifier> ::=
+ <SQL language identifier start>
+ [ { <underscore> | <SQL language identifier part> }... ]
+
+<SQL language identifier start> ::= <simple Latin letter>
+
+<SQL language identifier part> ::=
+ <simple Latin letter>
+ | <digit>
+
+<implementation-defined character repertoire name> ::=
+ <character set name>
+
+<user-defined character repertoire name> ::= <character set name>
+
+<standard universal character form-of-use name> ::=
+ <character set name>
+
+<implementation-defined universal character form-of-use name> ::=
+ <character set name>
+
+<date string> ::=
+ <quote> <date value> <quote>
+
+<date value> ::=
+ <years value> <minus sign> <months value>
+ <minus sign> <days value>
+
+<years value> ::= <datetime value>
+
+<datetime value> ::= <unsigned integer>
+
+<months value> ::= <datetime value>
+
+<days value> ::= <datetime value>
+
+<time string> ::=
+ <quote> <time value> [ <time zone interval> ] <quote>
+
+<time value> ::=
+ <hours value> <colon> <minutes value> <colon> <seconds value>
+
+<hours value> ::= <datetime value>
+
+<minutes value> ::= <datetime value>
+
+<seconds value> ::=
+ <seconds integer value> [ <period> [ <seconds fraction> ] ]
+
+<seconds integer value> ::= <unsigned integer>
+
+<seconds fraction> ::= <unsigned integer>
+
+<time zone interval> ::=
+ <sign> <hours value> <colon> <minutes value>
+
+<timestamp string> ::=
+ <quote> <date value> <space> <time value>
+ [ <time zone interval> ] <quote>
+
+<interval string> ::=
+ <quote> { <year-month literal> | <day-time literal> } <quote>
+
+<year-month literal> ::=
+ <years value>
+ | [ <years value> <minus sign> ] <months value>
+
+<day-time literal> ::=
+ <day-time interval>
+ | <time interval>
+
+<day-time interval> ::=
+ <days value>
+ [ <space> <hours value> [ <colon> <minutes value>
+ [ <colon> <seconds value> ] ] ]
+
+<time interval> ::=
+ <hours value> [ <colon> <minutes value> [ <colon> <seconds value> ] ]
+ | <minutes value> [ <colon> <seconds value> ]
+ | <seconds value>
+
+<not equals operator> ::= <>
+
+<greater than or equals operator> ::= >=
+
+<less than or equals operator> ::= <=
+
+<concatenation operator> ::= ||
+
+<double period> ::= ..
+
+<module> ::=
+ <module name clause>
+ <language clause>
+ <module authorization clause>
+ [ <temporary table declaration>... ]
+ <module contents>...
+
+<module name clause> ::=
+ MODULE [ <module name> ]
+ [ <module character set specification> ]
+
+<module name> ::= <identifier>
+
+<module character set specification> ::=
+ NAMES ARE <character set specification>
+
+<language clause> ::=
+ LANGUAGE <language name>
+
+<language name> ::=
+ ADA | C | COBOL | FORTRAN | MUMPS | PASCAL | PLI
+
+<module authorization clause> ::=
+ SCHEMA <schema name>
+ | AUTHORIZATION <module authorization identifier>
+ | SCHEMA <schema name>
+ AUTHORIZATION <module authorization identifier>
+
+<module authorization identifier> ::=
+ <authorization identifier>
+
+<authorization identifier> ::= <identifier>
+
+<temporary table declaration> ::=
+ DECLARE LOCAL TEMPORARY TABLE
+ <qualified local table name>
+ <table element list>
+ [ ON COMMIT { PRESERVE | DELETE } ROWS ]
+
+<qualified local table name> ::=
+ MODULE <period> <local table name>
+
+<local table name> ::= <qualified identifier>
+
+<qualified identifier> ::= <identifier>
+
+<table element list> ::=
+ <left paren> <table element> [ { <comma> <table element> }... ] <right paren>
+
+<table element> ::=
+ <column definition>
+ | <table constraint definition>
+
+<column definition> ::=
+ <column name> { <data type> | <domain name> }
+ [ <default clause> ]
+ [ <column constraint definition>... ]
+ [ <collate clause> ]
+
+<column name> ::= <identifier>
+
+<data type> ::=
+ <character string type>
+ [ CHARACTER SET <character set specification> ]
+ | <national character string type>
+ | <bit string type>
+ | <numeric type>
+ | <datetime type>
+ | <interval type>
+
+<character string type> ::=
+ CHARACTER [ <left paren> <length> <right paren> ]
+ | CHAR [ <left paren> <length> <right paren> ]
+ | CHARACTER VARYING <left paren> <length> <right paren>
+ | CHAR VARYING <left paren> <length> <right paren>
+ | VARCHAR <left paren> <length> <right paren>
+
+<length> ::= <unsigned integer>
+
+<national character string type> ::=
+ NATIONAL CHARACTER [ <left paren> <length> <right paren> ]
+ | NATIONAL CHAR [ <left paren> <length> <right paren> ]
+ | NCHAR [ <left paren> <length> <right paren> ]
+ | NATIONAL CHARACTER VARYING <left paren> <length> <right paren>
+ | NATIONAL CHAR VARYING <left paren> <length> <right paren>
+ | NCHAR VARYING <left paren> <length> <right paren>
+
+<bit string type> ::=
+ BIT [ <left paren> <length> <right paren> ]
+ | BIT VARYING <left paren> <length> <right paren>
+
+<numeric type> ::=
+ <exact numeric type>
+ | <approximate numeric type>
+
+<exact numeric type> ::=
+ NUMERIC [ <left paren> <precision> [ <comma> <scale> ] <right paren> ]
+ | DECIMAL [ <left paren> <precision> [ <comma> <scale> ] <right paren> ]
+ | DEC [ <left paren> <precision> [ <comma> <scale> ] <right paren> ]
+ | INTEGER
+ | INT
+ | SMALLINT
+
+<precision> ::= <unsigned integer>
+
+<scale> ::= <unsigned integer>
+
+<approximate numeric type> ::=
+ FLOAT [ <left paren> <precision> <right paren> ]
+ | REAL
+ | DOUBLE PRECISION
+
+<datetime type> ::=
+ DATE
+ | TIME [ <left paren> <time precision> <right paren> ]
+ [ WITH TIME ZONE ]
+ | TIMESTAMP [ <left paren> <timestamp precision> <right paren> ]
+ [ WITH TIME ZONE ]
+
+<time precision> ::= <time fractional seconds precision>
+
+<time fractional seconds precision> ::= <unsigned integer>
+
+<timestamp precision> ::= <time fractional seconds precision>
+
+<interval type> ::= INTERVAL <interval qualifier>
+
+<interval qualifier> ::=
+ <start field> TO <end field>
+ | <single datetime field>
+
+<start field> ::=
+ <non-second datetime field>
+ [ <left paren> <interval leading field precision> <right paren> ]
+
+<non-second datetime field> ::= YEAR | MONTH | DAY | HOUR
+ | MINUTE
+
+<interval leading field precision> ::= <unsigned integer>
+
+<end field> ::=
+ <non-second datetime field>
+ | SECOND [ <left paren> <interval fractional seconds precision> <right paren> ]
+
+<interval fractional seconds precision> ::= <unsigned integer>
+
+<single datetime field> ::=
+ <non-second datetime field>
+ [ <left paren> <interval leading field precision> <right paren> ]
+ | SECOND [ <left paren> <interval leading field precision>
+ [ <comma> <interval fractional seconds precision> ] <right paren> ]
+
+<domain name> ::= <qualified name>
+
+<qualified name> ::=
+ [ <schema name> <period> ] <qualified identifier>
+
+<default clause> ::=
+ DEFAULT <default option>
+
+<default option> ::=
+ <literal>
+ | <datetime value function>
+ | USER
+ | CURRENT_USER
+ | SESSION_USER
+ | SYSTEM_USER
+ | NULL
+
+<literal> ::=
+ <signed numeric literal>
+ | <general literal>
+
+<signed numeric literal> ::=
+ [ <sign> ] <unsigned numeric literal>
+
+<general literal> ::=
+ <character string literal>
+ | <national character string literal>
+ | <bit string literal>
+ | <hex string literal>
+ | <datetime literal>
+ | <interval literal>
+
+<datetime literal> ::=
+ <date literal>
+ | <time literal>
+ | <timestamp literal>
+
+<date literal> ::=
+ DATE <date string>
+
+<time literal> ::=
+ TIME <time string>
+
+<timestamp literal> ::=
+ TIMESTAMP <timestamp string>
+
+<interval literal> ::=
+ INTERVAL [ <sign> ] <interval string> <interval qualifier>
+
+<datetime value function> ::=
+ <current date value function>
+ | <current time value function>
+ | <current timestamp value function>
+
+<current date value function> ::= CURRENT_DATE
+
+<current time value function> ::=
+ CURRENT_TIME [ <left paren> <time precision> <right paren> ]
+
+<current timestamp value function> ::=
+ CURRENT_TIMESTAMP [ <left paren> <timestamp precision> <right paren> ]
+
+<column constraint definition> ::=
+ [ <constraint name definition> ]
+ <column constraint>
+ [ <constraint attributes> ]
+
+<constraint name definition> ::= CONSTRAINT <constraint name>
+
+<constraint name> ::= <qualified name>
+
+<column constraint> ::=
+ NOT NULL
+ | <unique specification>
+ | <references specification>
+ | <check constraint definition>
+
+<unique specification> ::=
+ UNIQUE | PRIMARY KEY
+
+<references specification> ::=
+ REFERENCES <referenced table and columns>
+ [ MATCH <match type> ]
+ [ <referential triggered action> ]
+
+<referenced table and columns> ::=
+ <table name> [ <left paren> <reference column list> <right paren> ]
+
+<table name> ::=
+ <qualified name>
+ | <qualified local table name>
+
+<reference column list> ::= <column name list>
+
+<column name list> ::=
+ <column name> [ { <comma> <column name> }... ]
+
+<match type> ::=
+ FULL
+ | PARTIAL
+
+<referential triggered action> ::=
+ <update rule> [ <delete rule> ]
+ | <delete rule> [ <update rule> ]
+
+<update rule> ::= ON UPDATE <referential action>
+
+<referential action> ::=
+ CASCADE
+ | SET NULL
+ | SET DEFAULT
+ | NO ACTION
+
+<delete rule> ::= ON DELETE <referential action>
+
+<check constraint definition> ::=
+ CHECK
+ <left paren> <search condition> <right paren>
+
+<search condition> ::=
+ <boolean term>
+ | <search condition> OR <boolean term>
+
+<boolean term> ::=
+ <boolean factor>
+ | <boolean term> AND <boolean factor>
+
+<boolean factor> ::=
+ [ NOT ] <boolean test>
+
+<boolean test> ::=
+ <boolean primary> [ IS [ NOT ]
+ <truth value> ]
+
+<boolean primary> ::=
+ <predicate>
+ | <left paren> <search condition> <right paren>
+
+<predicate> ::=
+ <comparison predicate>
+ | <between predicate>
+ | <in predicate>
+ | <like predicate>
+ | <null predicate>
+ | <quantified comparison predicate>
+ | <exists predicate>
+ | <unique predicate>
+ | <match predicate>
+ | <overlaps predicate>
+
+<comparison predicate> ::=
+ <row value constructor> <comp op>
+ <row value constructor>
+
+<row value constructor> ::=
+ <row value constructor element>
+ | <left paren> <row value constructor list> <right paren>
+ | <row subquery>
+
+<row value constructor element> ::=
+ <value expression>
+ | <null specification>
+ | <default specification>
+
+<value expression> ::=
+ <numeric value expression>
+ | <string value expression>
+ | <datetime value expression>
+ | <interval value expression>
+
+<numeric value expression> ::=
+ <term>
+ | <numeric value expression> <plus sign> <term>
+ | <numeric value expression> <minus sign> <term>
+
+<term> ::=
+ <factor>
+ | <term> <asterisk> <factor>
+ | <term> <solidus> <factor>
+
+<factor> ::=
+ [ <sign> ] <numeric primary>
+
+<numeric primary> ::=
+ <value expression primary>
+ | <numeric value function>
+
+<value expression primary> ::=
+ <unsigned value specification>
+ | <column reference>
+ | <set function specification>
+ | <scalar subquery>
+ | <case expression>
+ | <left paren> <value expression> <right paren>
+ | <cast specification>
+
+<unsigned value specification> ::=
+ <unsigned literal>
+ | <general value specification>
+
+<unsigned literal> ::=
+ <unsigned numeric literal>
+ | <general literal>
+
+<general value specification> ::=
+ <parameter specification>
+ | <dynamic parameter specification>
+ | <variable specification>
+ | USER
+ | CURRENT_USER
+ | SESSION_USER
+ | SYSTEM_USER
+ | VALUE
+
+<parameter specification> ::=
+ <parameter name> [ <indicator parameter> ]
+
+<parameter name> ::= <colon> <identifier>
+
+<indicator parameter> ::=
+ [ INDICATOR ] <parameter name>
+
+<dynamic parameter specification> ::= <question mark>
+
+<variable specification> ::=
+ <embedded variable name> [ <indicator variable> ]
+
+<embedded variable name> ::=
+ <colon><host identifier>
+
+<host identifier> ::=
+ <Ada host identifier>
+ | <C host identifier>
+ | <COBOL host identifier>
+ | <Fortran host identifier>
+ | <MUMPS host identifier>
+ | <Pascal host identifier>
+ | <PL/I host identifier>
+
+<Ada host identifier> ::= !! <EMPHASIS>(See the Syntax Rules.)
+
+<C host identifier> ::=
+ !! <EMPHASIS>(See the Syntax Rules.)
+
+<COBOL host identifier> ::= !! <EMPHASIS>(See the Syntax Rules.)
+
+<Fortran host identifier> ::= !! <EMPHASIS>(See the Syntax Rules.)
+
+<MUMPS host identifier> ::= !! <EMPHASIS>(See the Syntax Rules.)
+
+<Pascal host identifier> ::= !! <EMPHASIS>(See the Syntax Rules.)
+
+<PL/I host identifier> ::= !! <EMPHASIS>(See the Syntax Rules.)
+
+<indicator variable> ::=
+ [ INDICATOR ] <embedded variable name>
+
+<column reference> ::= [ <qualifier> <period> ] <column name>
+
+<qualifier> ::=
+ <table name>
+ | <correlation name>
+
+<correlation name> ::= <identifier>
+
+<set function specification> ::=
+ COUNT <left paren> <asterisk> <right paren>
+ | <general set function>
+
+<general set function> ::=
+ <set function type>
+ <left paren> [ <set quantifier> ] <value expression> <right paren>
+
+<set function type> ::=
+ AVG | MAX | MIN | SUM | COUNT
+
+<set quantifier> ::= DISTINCT | ALL
+
+<scalar subquery> ::= <subquery>
+
+<subquery> ::= <left paren> <query expression> <right paren>
+
+<query expression> ::=
+ <non-join query expression>
+ | <joined table>
+
+<non-join query expression> ::=
+ <non-join query term>
+ | <query expression> UNION [ ALL ]
+ [ <corresponding spec> ] <query term>
+ | <query expression> EXCEPT [ ALL ]
+ [ <corresponding spec> ] <query term>
+
+<non-join query term> ::=
+ <non-join query primary>
+ | <query term> INTERSECT [ ALL ]
+ [ <corresponding spec> ] <query primary>
+
+<non-join query primary> ::=
+ <simple table>
+ | <left paren> <non-join query expression> <right paren>
+
+<simple table> ::=
+ <query specification>
+ | <table value constructor>
+ | <explicit table>
+
+<query specification> ::=
+ SELECT [ <set quantifier> ] <select list> <table expression>
+
+<select list> ::=
+ <asterisk>
+ | <select sublist> [ { <comma> <select sublist> }... ]
+
+<select sublist> ::=
+ <derived column>
+ | <qualifier> <period> <asterisk>
+
+<derived column> ::= <value expression> [ <as clause> ]
+
+<as clause> ::= [ AS ] <column name>
+
+<table expression> ::=
+ <from clause>
+ [ <where clause> ]
+ [ <group by clause> ]
+ [ <having clause> ]
+
+<from clause> ::= FROM <table reference>
+ [ { <comma> <table reference> }... ]
+
+<table reference> ::=
+ <table name> [ [ AS ] <correlation name>
+ [ <left paren> <derived column list> <right paren> ] ]
+ | <derived table> [ AS ] <correlation name>
+ [ <left paren> <derived column list> <right paren> ]
+ | <joined table>
+
+<derived column list> ::= <column name list>
+
+<derived table> ::= <table subquery>
+
+<table subquery> ::= <subquery>
+
+<joined table> ::=
+ <cross join>
+ | <qualified join>
+ | <left paren> <joined table> <right paren>
+
+<cross join> ::=
+ <table reference> CROSS JOIN <table reference>
+
+<qualified join> ::=
+ <table reference> [ NATURAL ] [ <join type> ] JOIN
+ <table reference> [ <join specification> ]
+
+<join type> ::=
+ INNER
+ | <outer join type> [ OUTER ]
+ | UNION
+
+<outer join type> ::=
+ LEFT
+ | RIGHT
+ | FULL
+
+<join specification> ::=
+ <join condition>
+ | <named columns join>
+
+<join condition> ::= ON <search condition>
+
+<named columns join> ::=
+ USING <left paren> <join column list> <right paren>
+
+<join column list> ::= <column name list>
+
+<where clause> ::= WHERE <search condition>
+
+<group by clause> ::=
+ GROUP BY <grouping column reference list>
+
+<grouping column reference list> ::=
+ <grouping column reference>
+ [ { <comma> <grouping column reference> }... ]
+
+<grouping column reference> ::=
+ <column reference> [ <collate clause> ]
+
+<collate clause> ::= COLLATE <collation name>
+
+<collation name> ::= <qualified name>
+
+<having clause> ::= HAVING <search condition>
+
+<table value constructor> ::=
+ VALUES <table value constructor list>
+
+<table value constructor list> ::=
+ <row value constructor> [ { <comma> <row value constructor> }... ]
+
+<explicit table> ::= TABLE <table name>
+
+<query term> ::=
+ <non-join query term>
+ | <joined table>
+
+<corresponding spec> ::=
+ CORRESPONDING [ BY <left paren> <corresponding column list> <right paren> ]
+
+<corresponding column list> ::= <column name list>
+
+<query primary> ::=
+ <non-join query primary>
+ | <joined table>
+
+<case expression> ::=
+ <case abbreviation>
+ | <case specification>
+
+<case abbreviation> ::=
+ NULLIF <left paren> <value expression> <comma>
+ <value expression> <right paren>
+ | COALESCE <left paren> <value expression>
+ { <comma> <value expression> }... <right paren>
+
+<case specification> ::=
+ <simple case>
+ | <searched case>
+
+<simple case> ::=
+ CASE <case operand>
+ <simple when clause>...
+ [ <else clause> ]
+ END
+
+<case operand> ::= <value expression>
+
+<simple when clause> ::= WHEN <when operand> THEN <result>
+
+<when operand> ::= <value expression>
+
+<result> ::= <result expression> | NULL
+
+<result expression> ::= <value expression>
+
+<else clause> ::= ELSE <result>
+
+<searched case> ::=
+ CASE
+ <searched when clause>...
+ [ <else clause> ]
+ END
+
+<searched when clause> ::= WHEN <search condition> THEN <result>
+
+<cast specification> ::=
+ CAST <left paren> <cast operand> AS
+ <cast target> <right paren>
+
+<cast operand> ::=
+ <value expression>
+ | NULL
+
+<cast target> ::=
+ <domain name>
+ | <data type>
+
+<numeric value function> ::=
+ <position expression>
+ | <extract expression>
+ | <length expression>
+
+<position expression> ::=
+ POSITION <left paren> <character value expression>
+ IN <character value expression> <right paren>
+
+<character value expression> ::=
+ <concatenation>
+ | <character factor>
+
+<concatenation> ::=
+ <character value expression> <concatenation operator>
+ <character factor>
+
+<character factor> ::=
+ <character primary> [ <collate clause> ]
+
+<character primary> ::=
+ <value expression primary>
+ | <string value function>
+
+<string value function> ::=
+ <character value function>
+ | <bit value function>
+
+<character value function> ::=
+ <character substring function>
+ | <fold>
+ | <form-of-use conversion>
+ | <character translation>
+ | <trim function>
+
+<character substring function> ::=
+ SUBSTRING <left paren> <character value expression> FROM <start position>
+ [ FOR <string length> ] <right paren>
+
+<start position> ::= <numeric value expression>
+
+<string length> ::= <numeric value expression>
+
+<fold> ::= { UPPER | LOWER }
+ <left paren> <character value expression> <right paren>
+
+<form-of-use conversion> ::=
+ CONVERT <left paren> <character value expression>
+ USING <form-of-use conversion name> <right paren>
+
+<form-of-use conversion name> ::= <qualified name>
+
+<character translation> ::=
+ TRANSLATE <left paren> <character value expression>
+ USING <translation name> <right paren>
+
+<translation name> ::= <qualified name>
+
+<trim function> ::=
+ TRIM <left paren> <trim operands> <right paren>
+
+<trim operands> ::=
+ [ [ <trim specification> ] [ <trim character> ] FROM ] <trim source>
+
+<trim specification> ::=
+ LEADING
+ | TRAILING
+ | BOTH
+
+<trim character> ::= <character value expression>
+
+<trim source> ::= <character value expression>
+
+<bit value function> ::=
+ <bit substring function>
+
+<bit substring function> ::=
+ SUBSTRING <left paren> <bit value expression> FROM <start position>
+ [ FOR <string length> ] <right paren>
+
+<bit value expression> ::=
+ <bit concatenation>
+ | <bit factor>
+
+<bit concatenation> ::=
+ <bit value expression> <concatenation operator> <bit factor>
+
+<bit factor> ::= <bit primary>
+
+<bit primary> ::=
+ <value expression primary>
+ | <string value function>
+
+<extract expression> ::=
+ EXTRACT <left paren> <extract field>
+ FROM <extract source> <right paren>
+
+<extract field> ::=
+ <datetime field>
+ | <time zone field>
+
+<datetime field> ::=
+ <non-second datetime field>
+ | SECOND
+
+<time zone field> ::=
+ TIMEZONE_HOUR
+ | TIMEZONE_MINUTE
+
+<extract source> ::=
+ <datetime value expression>
+ | <interval value expression>
+
+<datetime value expression> ::=
+ <datetime term>
+ | <interval value expression> <plus sign> <datetime term>
+ | <datetime value expression> <plus sign> <interval term>
+ | <datetime value expression> <minus sign> <interval term>
+
+<interval term> ::=
+ <interval factor>
+ | <interval term 2> <asterisk> <factor>
+ | <interval term 2> <solidus> <factor>
+ | <term> <asterisk> <interval factor>
+
+<interval factor> ::=
+ [ <sign> ] <interval primary>
+
+<interval primary> ::=
+ <value expression primary> [ <interval qualifier> ]
+
+<interval term 2> ::= <interval term>
+
+<interval value expression> ::=
+ <interval term>
+ | <interval value expression 1> <plus sign> <interval term 1>
+ | <interval value expression 1> <minus sign> <interval term 1>
+ | <left paren> <datetime value expression> <minus sign>
+ <datetime term> <right paren> <interval qualifier>
+
+<interval value expression 1> ::= <interval value expression>
+
+<interval term 1> ::= <interval term>
+
+<datetime term> ::=
+ <datetime factor>
+
+<datetime factor> ::=
+ <datetime primary> [ <time zone> ]
+
+<datetime primary> ::=
+ <value expression primary>
+ | <datetime value function>
+
+<time zone> ::=
+ AT <time zone specifier>
+
+<time zone specifier> ::=
+ LOCAL
+ | TIME ZONE <interval value expression>
+
+<length expression> ::=
+ <char length expression>
+ | <octet length expression>
+ | <bit length expression>
+
+<char length expression> ::=
+ { CHAR_LENGTH | CHARACTER_LENGTH }
+ <left paren> <string value expression> <right paren>
+
+<string value expression> ::=
+ <character value expression>
+ | <bit value expression>
+
+<octet length expression> ::=
+ OCTET_LENGTH <left paren> <string value expression> <right paren>
+
+<bit length expression> ::=
+ BIT_LENGTH <left paren> <string value expression> <right paren>
+
+<null specification> ::=
+ NULL
+
+<default specification> ::=
+ DEFAULT
+
+<row value constructor list> ::=
+ <row value constructor element>
+ [ { <comma> <row value constructor element> }... ]
+
+<row subquery> ::= <subquery>
+
+<comp op> ::=
+ <equals operator>
+ | <not equals operator>
+ | <less than operator>
+ | <greater than operator>
+ | <less than or equals operator>
+ | <greater than or equals operator>
+
+<between predicate> ::=
+ <row value constructor> [ NOT ] BETWEEN
+ <row value constructor> AND <row value constructor>
+
+<in predicate> ::=
+ <row value constructor>
+ [ NOT ] IN <in predicate value>
+
+<in predicate value> ::=
+ <table subquery>
+ | <left paren> <in value list> <right paren>
+
+<in value list> ::=
+ <value expression> { <comma> <value expression> }...
+
+<like predicate> ::=
+ <match value> [ NOT ] LIKE <pattern>
+ [ ESCAPE <escape character> ]
+
+<match value> ::= <character value expression>
+
+<pattern> ::= <character value expression>
+
+<escape character> ::= <character value expression>
+
+<null predicate> ::= <row value constructor>
+ IS [ NOT ] NULL
+
+<quantified comparison predicate> ::=
+ <row value constructor> <comp op> <quantifier> <table subquery>
+
+<quantifier> ::= <all> | <some>
+
+<all> ::= ALL
+
+<some> ::= SOME | ANY
+
+<exists predicate> ::= EXISTS <table subquery>
+
+<unique predicate> ::= UNIQUE <table subquery>
+
+<match predicate> ::=
+ <row value constructor> MATCH [ UNIQUE ]
+ [ PARTIAL | FULL ] <table subquery>
+
+<overlaps predicate> ::=
+ <row value constructor 1> OVERLAPS <row value constructor 2>
+
+<row value constructor 1> ::= <row value constructor>
+
+<row value constructor 2> ::= <row value constructor>
+
+<truth value> ::=
+ TRUE
+ | FALSE
+ | UNKNOWN
+
+<constraint attributes> ::=
+ <constraint check time> [ [ NOT ] DEFERRABLE ]
+ | [ NOT ] DEFERRABLE [ <constraint check time> ]
+
+<constraint check time> ::=
+ INITIALLY DEFERRED
+ | INITIALLY IMMEDIATE
+
+<table constraint definition> ::=
+ [ <constraint name definition> ]
+ <table constraint> [ <constraint attributes> ]
+
+<table constraint> ::=
+ <unique constraint definition>
+ | <referential constraint definition>
+ | <check constraint definition>
+
+<unique constraint definition> ::=
+ <unique specification> even in SQL3)
+ <unique specification>
+ <left paren> <unique column list> <right paren>
+
+<unique column list> ::= <column name list>
+
+<referential constraint definition> ::=
+ FOREIGN KEY
+ <left paren> <referencing columns> <right paren>
+ <references specification>
+
+<referencing columns> ::=
+ <reference column list>
+
+<module contents> ::=
+ <declare cursor>
+ | <dynamic declare cursor>
+ | <procedure>
+
+<declare cursor> ::=
+ DECLARE <cursor name> [ INSENSITIVE ] [ SCROLL ] CURSOR
+ FOR <cursor specification>
+
+<cursor name> ::= <identifier>
+
+<cursor specification> ::=
+ <query expression> [ <order by clause> ]
+ [ <updatability clause> ]
+
+<order by clause> ::=
+ ORDER BY <sort specification list>
+
+<sort specification list> ::=
+ <sort specification> [ { <comma> <sort specification> }... ]
+
+<sort specification> ::=
+ <sort key> [ <collate clause> ] [ <ordering specification> ]
+
+<sort key> ::=
+ <column name>
+ | <unsigned integer>
+
+<ordering specification> ::= ASC | DESC
+
+<updatability clause> ::=
+ FOR
+ { READ ONLY |
+ UPDATE [ OF <column name list> ] }
+
+<dynamic declare cursor> ::=
+ DECLARE <cursor name> [ INSENSITIVE ] [ SCROLL ] CURSOR
+ FOR <statement name>
+
+<statement name> ::= <identifier>
+
+<procedure> ::=
+ PROCEDURE <procedure name>
+ <parameter declaration list> <semicolon>
+ <SQL procedure statement> <semicolon>
+
+<procedure name> ::= <identifier>
+
+<parameter declaration list> ::=
+ <left paren> <parameter declaration>
+ [ { <comma> <parameter declaration> }... ] <right paren>
+ | <parameter declaration>...
+
+<parameter declaration> ::=
+ <parameter name> <data type>
+ | <status parameter>
+
+<status parameter> ::=
+ SQLCODE | SQLSTATE
+
+<SQL procedure statement> ::=
+ <SQL schema statement>
+ | <SQL data statement>
+ | <SQL transaction statement>
+ | <SQL connection statement>
+ | <SQL session statement>
+ | <SQL dynamic statement>
+ | <SQL diagnostics statement>
+
+<SQL schema statement> ::=
+ <SQL schema definition statement>
+ | <SQL schema manipulation statement>
+
+<SQL schema definition statement> ::=
+ <schema definition>
+ | <table definition>
+ | <view definition>
+ | <grant statement>
+ | <domain definition>
+ | <character set definition>
+ | <collation definition>
+ | <translation definition>
+ | <assertion definition>
+
+<schema definition> ::=
+ CREATE SCHEMA <schema name clause>
+ [ <schema character set specification> ]
+ [ <schema element>... ]
+
+<schema name clause> ::=
+ <schema name>
+ | AUTHORIZATION <schema authorization identifier>
+ | <schema name> AUTHORIZATION
+ <schema authorization identifier>
+
+<schema authorization identifier> ::=
+ <authorization identifier>
+
+<schema character set specification> ::=
+ DEFAULT CHARACTER
+ SET <character set specification>
+
+<schema element> ::=
+ <domain definition>
+ | <table definition>
+ | <view definition>
+ | <grant statement>
+ | <assertion definition>
+ | <character set definition>
+ | <collation definition>
+ | <translation definition>
+
+<domain definition> ::=
+ CREATE DOMAIN <domain name>
+ [ AS ] <data type>
+ [ <default clause> ]
+ [ <domain constraint>... ]
+ [ <collate clause> ]
+
+<domain constraint> ::=
+ [ <constraint name definition> ]
+ <check constraint definition> [ <constraint attributes> ]
+
+<table definition> ::=
+ CREATE [ { GLOBAL | LOCAL } TEMPORARY ] TABLE
+ <table name>
+ <table element list>
+ [ ON COMMIT { DELETE | PRESERVE } ROWS ]
+
+<view definition> ::=
+ CREATE VIEW <table name> [ <left paren> <view column list>
+ <right paren> ]
+ AS <query expression>
+ [ WITH [ <levels clause> ] CHECK OPTION ]
+
+<view column list> ::= <column name list>
+
+<levels clause> ::=
+ CASCADED | LOCAL
+
+<grant statement> ::=
+ GRANT <privileges> ON <object name>
+ TO <grantee> [ { <comma> <grantee> }... ]
+ [ WITH GRANT OPTION ]
+
+<privileges> ::=
+ ALL PRIVILEGES
+ | <action list>
+
+<action list> ::= <action> [ { <comma> <action> }... ]
+
+<action> ::=
+ SELECT
+ | DELETE
+ | INSERT [ <left paren> <privilege column list> <right paren> ]
+ | UPDATE [ <left paren> <privilege column list> <right paren> ]
+ | REFERENCES [ <left paren> <privilege column list> <right paren> ]
+ | USAGE
+
+<privilege column list> ::= <column name list>
+
+<object name> ::=
+ [ TABLE ] <table name>
+ | DOMAIN <domain name>
+ | COLLATION <collation name>
+ | CHARACTER SET <character set name>
+ | TRANSLATION <translation name>
+
+<grantee> ::=
+ PUBLIC
+ | <authorization identifier>
+
+<assertion definition> ::=
+ CREATE ASSERTION <constraint name> <assertion check>
+ [ <constraint attributes> ]
+
+<assertion check> ::=
+ CHECK
+ <left paren> <search condition> <right paren>
+
+<character set definition> ::=
+ CREATE CHARACTER SET <character set name>
+ [ AS ]
+ <character set source>
+ [ <collate clause> | <limited collation definition> ]
+
+<character set source> ::=
+ GET <existing character set name>
+
+<existing character set name> ::=
+ <standard character repertoire name>
+ | <implementation-defined character repertoire name>
+ | <schema character set name>
+
+<schema character set name> ::= <character set name>
+
+<limited collation definition> ::=
+ COLLATION FROM <collation source>
+
+<collation source> ::=
+ <collating sequence definition>
+ | <translation collation>
+
+<collating sequence definition> ::=
+ <external collation>
+ | <schema collation name>
+ | DESC <left paren> <collation name> <right paren>
+ | DEFAULT
+
+<external collation> ::=
+ EXTERNAL <left paren> <quote> <external collation name> <quote> <right paren>
+
+<external collation name> ::=
+ <standard collation name>
+ | <implementation-defined collation name>
+
+<standard collation name> ::= <collation name>
+
+<implementation-defined collation name> ::= <collation name>
+
+<schema collation name> ::= <collation name>
+
+<translation collation> ::=
+ TRANSLATION <translation name>
+ [ THEN COLLATION <collation name> ]
+
+<collation definition> ::=
+ CREATE COLLATION <collation name> FOR
+ <character set specification>
+ FROM <collation source>
+ [ <pad attribute> ]
+
+<pad attribute> ::=
+ NO PAD
+ | PAD SPACE
+
+<translation definition> ::=
+ CREATE TRANSLATION <translation name>
+ FOR <source character set specification>
+ TO <target character set specification>
+ FROM <translation source>
+
+<source character set specification> ::= <character set specification>
+
+<target character set specification> ::= <character set specification>
+
+<translation source> ::=
+ <translation specification>
+
+<translation specification> ::=
+ <external translation>
+ | IDENTITY
+ | <schema translation name>
+
+<external translation> ::=
+ EXTERNAL <left paren> <quote> <external translation name> <quote> <right paren>
+
+<external translation name> ::=
+ <standard translation name>
+ | <implementation-defined translation name>
+
+<standard translation name> ::= <translation name>
+
+<implementation-defined translation name> ::= <translation name>
+
+<schema translation name> ::= <translation name>
+
+<SQL schema manipulation statement> ::=
+ <drop schema statement>
+ | <alter table statement>
+ | <drop table statement>
+ | <drop view statement>
+ | <revoke statement>
+ | <alter domain statement>
+ | <drop domain statement>
+ | <drop character set statement>
+ | <drop collation statement>
+ | <drop translation statement>
+ | <drop assertion statement>
+
+<drop schema statement> ::=
+ DROP SCHEMA <schema name> <drop behavior>
+
+<drop behavior> ::= CASCADE | RESTRICT
+
+<alter table statement> ::=
+ ALTER TABLE <table name> <alter table action>
+
+<alter table action> ::=
+ <add column definition>
+ | <alter column definition>
+ | <drop column definition>
+ | <add table constraint definition>
+ | <drop table constraint definition>
+
+<add column definition> ::=
+ ADD [ COLUMN ] <column definition>
+
+<alter column definition> ::=
+ ALTER [ COLUMN ] <column name> <alter column action>
+
+<alter column action> ::=
+ <set column default clause>
+ | <drop column default clause>
+
+<set column default clause> ::=
+ SET <default clause>
+
+<drop column default clause> ::=
+ DROP DEFAULT
+
+<drop column definition> ::=
+ DROP [ COLUMN ] <column name> <drop behavior>
+
+<add table constraint definition> ::=
+ ADD <table constraint definition>
+
+<drop table constraint definition> ::=
+ DROP CONSTRAINT <constraint name> <drop behavior>
+
+<drop table statement> ::=
+ DROP TABLE <table name> <drop behavior>
+
+<drop view statement> ::=
+ DROP VIEW <table name> <drop behavior>
+
+<revoke statement> ::=
+ REVOKE [ GRANT OPTION FOR ]
+ <privileges>
+ ON <object name>
+ FROM <grantee> [ { <comma> <grantee> }... ] <drop behavior>
+
+<alter domain statement> ::=
+ ALTER DOMAIN <domain name> <alter domain action>
+
+<alter domain action> ::=
+ <set domain default clause>
+ | <drop domain default clause>
+ | <add domain constraint definition>
+ | <drop domain constraint definition>
+
+<set domain default clause> ::= SET <default clause>
+
+<drop domain default clause> ::= DROP DEFAULT
+
+<add domain constraint definition> ::=
+ ADD <domain constraint>
+
+<drop domain constraint definition> ::=
+ DROP CONSTRAINT <constraint name>
+
+<drop domain statement> ::=
+ DROP DOMAIN <domain name> <drop behavior>
+
+<drop character set statement> ::=
+ DROP CHARACTER SET <character set name>
+
+<drop collation statement> ::=
+ DROP COLLATION <collation name>
+
+<drop translation statement> ::=
+ DROP TRANSLATION <translation name>
+
+<drop assertion statement> ::=
+ DROP ASSERTION <constraint name>
+
+<SQL data statement> ::=
+ <open statement>
+ | <fetch statement>
+ | <close statement>
+ | <select statement: single row>
+ | <SQL data change statement>
+
+<open statement> ::=
+ OPEN <cursor name>
+
+<fetch statement> ::=
+ FETCH [ [ <fetch orientation> ] FROM ]
+ <cursor name> INTO <fetch target list>
+
+<fetch orientation> ::=
+ NEXT
+ | PRIOR
+ | FIRST
+ | LAST
+ | { ABSOLUTE | RELATIVE } <simple value specification>
+
+<simple value specification> ::=
+ <parameter name>
+ | <embedded variable name>
+ | <literal>
+
+<fetch target list> ::=
+ <target specification> [ { <comma> <target specification> }... ]
+
+<target specification> ::=
+ <parameter specification>
+ | <variable specification>
+
+<close statement> ::=
+ CLOSE <cursor name>
+
+<select statement: single row> ::=
+ SELECT [ <set quantifier> ] <select list>
+ INTO <select target list>
+ <table expression>
+
+<select target list> ::=
+ <target specification> [ { <comma> <target specification> }... ]
+
+<SQL data change statement> ::=
+ <delete statement: positioned>
+ | <delete statement: searched>
+ | <insert statement>
+ | <update statement: positioned>
+ | <update statement: searched>
+
+<delete statement: positioned> ::=
+ DELETE FROM <table name>
+ WHERE CURRENT OF <cursor name>
+
+<delete statement: searched> ::=
+ DELETE FROM <table name>
+ [ WHERE <search condition> ]
+
+<insert statement> ::=
+ INSERT INTO <table name>
+ <insert columns and source>
+
+<insert columns and source> ::=
+ [ <left paren> <insert column list> <right paren> ]
+ <query expression>
+ | DEFAULT VALUES
+
+<insert column list> ::= <column name list>
+
+<update statement: positioned> ::=
+ UPDATE <table name>
+ SET <set clause list>
+ WHERE CURRENT OF <cursor name>
+
+<set clause list> ::=
+ <set clause> [ { <comma> <set clause> }... ]
+
+<set clause> ::=
+ <object column> <equals operator> <update source>
+
+<object column> ::= <column name>
+
+<update source> ::=
+ <value expression>
+ | <null specification>
+ | DEFAULT
+
+<update statement: searched> ::=
+ UPDATE <table name>
+ SET <set clause list>
+ [ WHERE <search condition> ]
+
+<SQL transaction statement> ::=
+ <set transaction statement>
+ | <set constraints mode statement>
+ | <commit statement>
+ | <rollback statement>
+
+<set transaction statement> ::=
+ SET TRANSACTION <transaction mode>
+ [ { <comma> <transaction mode> }... ]
+
+<transaction mode> ::=
+ <isolation level>
+ | <transaction access mode>
+ | <diagnostics size>
+
+<isolation level> ::=
+ ISOLATION LEVEL <level of isolation>
+
+<level of isolation> ::=
+ READ UNCOMMITTED
+ | READ COMMITTED
+ | REPEATABLE READ
+ | SERIALIZABLE
+
+<transaction access mode> ::=
+ READ ONLY
+ | READ WRITE
+
+<diagnostics size> ::=
+ DIAGNOSTICS SIZE <number of conditions>
+
+<number of conditions> ::= <simple value specification>
+
+<set constraints mode statement> ::=
+ SET CONSTRAINTS <constraint name list>
+ { DEFERRED | IMMEDIATE }
+
+<constraint name list> ::=
+ ALL
+ | <constraint name> [ { <comma> <constraint name> }... ]
+
+<commit statement> ::=
+ COMMIT [ WORK ]
+
+<rollback statement> ::=
+ ROLLBACK [ WORK ]
+
+<SQL connection statement> ::=
+ <connect statement>
+ | <set connection statement>
+ | <disconnect statement>
+
+<connect statement> ::=
+ CONNECT TO <connection target>
+
+<connection target> ::=
+ <SQL-server name>
+ [ AS <connection name> ]
+ correspondence with Tony Gordon)
+ [ USER <user name> ]
+ | DEFAULT
+
+<SQL-server name> ::= <simple value specification>
+
+<connection name> ::= <simple value specification>
+
+<user name> ::= <simple value specification>
+
+<set connection statement> ::=
+ SET CONNECTION <connection object>
+
+<connection object> ::=
+ DEFAULT
+ | <connection name>
+
+<disconnect statement> ::=
+ DISCONNECT <disconnect object>
+
+<disconnect object> ::=
+ <connection object>
+ | ALL
+ | CURRENT
+
+<SQL session statement> ::=
+ <set catalog statement>
+ | <set schema statement>
+ | <set names statement>
+ | <set session authorization identifier statement>
+ | <set local time zone statement>
+
+<set catalog statement> ::=
+ SET CATALOG <value specification>
+
+<value specification> ::=
+ <literal>
+ | <general value specification>
+
+<set schema statement> ::=
+ SET SCHEMA <value specification>
+
+<set names statement> ::=
+ SET NAMES <value specification>
+
+<set session authorization identifier statement> ::=
+ SET SESSION AUTHORIZATION
+ <value specification>
+
+<set local time zone statement> ::=
+ SET TIME ZONE
+ <set time zone value>
+
+<set time zone value> ::=
+ <interval value expression>
+ | LOCAL
+
+<SQL dynamic statement> ::=
+ <system descriptor statement>
+ | <prepare statement>
+ | <deallocate prepared statement>
+ | <describe statement>
+ | <execute statement>
+ | <execute immediate statement>
+ | <SQL dynamic data statement>
+
+<system descriptor statement> ::=
+ <allocate descriptor statement>
+ | <deallocate descriptor statement>
+ | <set descriptor statement>
+ | <get descriptor statement>
+
+<allocate descriptor statement> ::=
+ ALLOCATE DESCRIPTOR <descriptor name>
+ [ WITH MAX <occurrences> ]
+
+<descriptor name> ::=
+ [ <scope option> ] <simple value specification>
+
+<scope option> ::=
+ GLOBAL
+ | LOCAL
+
+<occurrences> ::= <simple value specification>
+
+<deallocate descriptor statement> ::=
+ DEALLOCATE DESCRIPTOR <descriptor name>
+
+<set descriptor statement> ::=
+ SET DESCRIPTOR <descriptor name>
+ <set descriptor information>
+
+<set descriptor information> ::=
+ <set count>
+ | VALUE <item number>
+ <set item information> [ { <comma> <set item information> }... ]
+
+<set count> ::=
+ COUNT <equals operator> <simple value specification 1>
+
+<simple value specification 1> ::= <simple value specification>
+
+<item number> ::= <simple value specification>
+
+<set item information> ::=
+ <descriptor item name> <equals operator> <simple value specification 2>
+
+<descriptor item name> ::=
+ TYPE
+ | LENGTH
+ | OCTET_LENGTH
+ | RETURNED_LENGTH
+ | RETURNED_OCTET_LENGTH
+ | PRECISION
+ | SCALE
+ | DATETIME_INTERVAL_CODE
+ | DATETIME_INTERVAL_PRECISION
+ | NULLABLE
+ | INDICATOR
+ | DATA
+ | NAME
+ | UNNAMED
+ | COLLATION_CATALOG
+ | COLLATION_SCHEMA
+ | COLLATION_NAME
+ | CHARACTER_SET_CATALOG
+ | CHARACTER_SET_SCHEMA
+ | CHARACTER_SET_NAME
+
+<simple value specification 2> ::= <simple value specification>
+
+<item number> ::= <simple value specification>
+
+<get descriptor statement> ::=
+ GET DESCRIPTOR <descriptor name> <get descriptor information>
+
+<get descriptor information> ::=
+ <get count>
+ | VALUE <item number>
+ <get item information> [ { <comma> <get item information> }... ]
+
+<get count> ::=
+ <simple target specification 1> <equals operator>
+ COUNT
+
+<simple target specification 1> ::= <simple target specification>
+
+<simple target specification> ::=
+ <parameter name>
+ | <embedded variable name>
+
+<get item information> ::=
+ <simple target specification 2> <equals operator> <descriptor item name>>
+
+<simple target specification 2> ::= <simple target specification>
+
+<prepare statement> ::=
+ PREPARE <SQL statement name> FROM <SQL statement variable>
+
+<SQL statement name> ::=
+ <statement name>
+ | <extended statement name>
+
+<extended statement name> ::=
+ [ <scope option> ] <simple value specification>
+
+<SQL statement variable> ::= <simple value specification>
+
+<deallocate prepared statement> ::=
+ DEALLOCATE PREPARE <SQL statement name>
+
+<describe statement> ::=
+ <describe input statement>
+ | <describe output statement>
+
+<describe input statement> ::=
+ DESCRIBE INPUT <SQL statement name> <using descriptor>
+
+<using descriptor> ::=
+ { USING | INTO } SQL DESCRIPTOR <descriptor name>
+
+<describe output statement> ::=
+ DESCRIBE [ OUTPUT ] <SQL statement name> <using descriptor>
+
+<execute statement> ::=
+ EXECUTE <SQL statement name>
+ [ <result using clause> ]
+ [ <parameter using clause> ]
+
+<result using clause> ::= <using clause>
+
+<using clause> ::=
+ <using arguments>
+ | <using descriptor>
+
+<using arguments> ::=
+ { USING | INTO } <argument> [ { <comma> <argument> }... ]
+
+<argument> ::= <target specification>
+
+<parameter using clause> ::= <using clause>
+
+<execute immediate statement> ::=
+ EXECUTE IMMEDIATE <SQL statement variable>
+
+<SQL dynamic data statement> ::=
+ <allocate cursor statement>
+ | <dynamic open statement>
+ | <dynamic fetch statement>
+ | <dynamic close statement>
+ | <dynamic delete statement: positioned>
+ | <dynamic update statement: positioned>
+
+<allocate cursor statement> ::=
+ ALLOCATE <extended cursor name> [ INSENSITIVE ]
+ [ SCROLL ] CURSOR
+ FOR <extended statement name>
+
+<extended cursor name> ::=
+ [ <scope option> ] <simple value specification>
+
+<dynamic open statement> ::=
+ OPEN <dynamic cursor name> [ <using clause> ]
+
+<dynamic cursor name> ::=
+ <cursor name>
+ | <extended cursor name>
+
+<dynamic fetch statement> ::=
+ FETCH [ [ <fetch orientation> ] FROM ] <dynamic cursor name>
+ <using clause>
+
+<dynamic close statement> ::=
+ CLOSE <dynamic cursor name>
+
+<dynamic delete statement: positioned> ::=
+ DELETE FROM <table name>
+ WHERE CURRENT OF
+ <dynamic cursor name>
+
+<dynamic update statement: positioned> ::=
+ UPDATE <table name>
+ SET <set clause>
+ [ { <comma> <set clause> }... ]
+ WHERE CURRENT OF
+ <dynamic cursor name>
+
+<SQL diagnostics statement> ::=
+ <get diagnostics statement>
+
+<get diagnostics statement> ::=
+ GET DIAGNOSTICS <sql diagnostics information>
+
+<sql diagnostics information> ::=
+ <statement information>
+ | <condition information>
+
+<statement information> ::=
+ <statement information item> [ { <comma> <statement information item> }... ]
+
+<statement information item> ::=
+ <simple target specification> <equals operator> <statement information item name>
+
+<statement information item name> ::=
+ NUMBER
+ | MORE
+ | COMMAND_FUNCTION
+ | DYNAMIC_FUNCTION
+ | ROW_COUNT
+
+<condition information> ::=
+ EXCEPTION <condition number>
+ <condition information item> [ { <comma> <condition information item> }... ]
+
+<condition number> ::= <simple value specification>
+
+<condition information item> ::=
+ <simple target specification> <equals operator> <condition information item name>
+
+<condition information item name> ::=
+ CONDITION_NUMBER
+ | RETURNED_SQLSTATE
+ | CLASS_ORIGIN
+ | SUBCLASS_ORIGIN
+ | SERVER_NAME
+ | CONNECTION_NAME
+ | CONSTRAINT_CATALOG
+ | CONSTRAINT_SCHEMA
+ | CONSTRAINT_NAME
+ | CATALOG_NAME
+ | SCHEMA_NAME
+ | TABLE_NAME
+ | COLUMN_NAME
+ | CURSOR_NAME
+ | MESSAGE_TEXT
+ | MESSAGE_LENGTH
+ | MESSAGE_OCTET_LENGTH
+
+<embedded SQL host program> ::=
+ <embedded SQL Ada program>
+ | <embedded SQL C program>
+ | <embedded SQL COBOL program>
+ | <embedded SQL Fortran program>
+ | <embedded SQL MUMPS program>
+ | <embedded SQL Pascal program>
+ | <embedded SQL PL/I program>
+
+<embedded SQL Ada program> ::= !! <EMPHASIS>(See the Syntax Rules.)
+
+<embedded SQL C program> ::=
+ !! <EMPHASIS>(See the Syntax Rules.)
+
+<embedded SQL COBOL program> ::= !! <EMPHASIS>(See the Syntax Rules.)
+
+<embedded SQL Fortran program> ::=
+ !! <EMPHASIS>(See the Syntax Rules.)
+
+<embedded SQL MUMPS program> ::= !! <EMPHASIS>(See the Syntax Rules.)
+
+<embedded SQL Pascal program> ::=
+ !! <EMPHASIS>(See the Syntax Rules.)
+
+<embedded SQL PL/I program> ::= !! <EMPHASIS>(See the Syntax Rules.)
+
+<embedded SQL declare section> ::=
+ <embedded SQL begin declare>
+ [ <embedded character set declaration> ]
+ [ <host variable definition>... ]
+ <embedded SQL end declare>
+ | <embedded SQL MUMPS declare>
+
+<embedded SQL begin declare> ::=
+ <SQL prefix> BEGIN DECLARE SECTION
+ [ <SQL terminator> ]
+
+<SQL prefix> ::=
+ EXEC SQL
+ | <ampersand>SQL<left paren>
+
+<SQL terminator> ::=
+ END-EXEC
+ | <semicolon>
+ | <right paren>
+
+<embedded character set declaration> ::=
+ SQL NAMES ARE <character set specification>
+
+<host variable definition> ::=
+ <Ada variable definition>
+ | <C variable definition>
+ | <COBOL variable definition>
+ | <Fortran variable definition>
+ | <MUMPS variable definition>
+ | <Pascal variable definition>
+ | <PL/I variable definition>
+
+<Ada variable definition> ::=
+ <Ada host identifier> [ { <comma> <Ada host identifier> }... ] :
+ <Ada type specification> [ <Ada initial value> ]
+
+<Ada type specification> ::=
+ <Ada qualified type specification>
+ | <Ada unqualified type specification>
+
+<Ada qualified type specification> ::=
+ SQL_STANDARD.CHAR [ CHARACTER SET
+ [ IS ] <character set specification> ]
+ <left paren> 1 <double period> <length> <right paren>
+ | SQL_STANDARD.BIT
+ <left paren> 1 <double period> <length> <right paren>
+ | SQL_STANDARD.SMALLINT
+ | SQL_STANDARD.INT
+ | SQL_STANDARD.REAL
+ | SQL_STANDARD.DOUBLE_PRECISION
+ | SQL_STANDARD.SQLCODE_TYPE
+ | SQL_STANDARD.SQLSTATE_TYPE
+ | SQL_STANDARD.INDICATOR_TYPE
+
+<Ada unqualified type specification> ::=
+ CHAR
+ <left paren> 1 <double period> <length> <right paren>
+ | BIT
+ <left paren> 1 <double period> <length> <right paren>
+ | SMALLINT
+ | INT
+ | REAL
+ | DOUBLE_PRECISION
+ | SQLCODE_TYPE
+ | SQLSTATE_TYPE
+ | INDICATOR_TYPE
+
+<Ada initial value> ::=
+ <Ada assignment operator> <character representation>...
+
+<Ada assignment operator> ::= <colon><equals operator>
+
+<C variable definition> ::=
+ [ <C storage class> ]
+ [ <C class modifier> ]
+ <C variable specification>
+ <semicolon>
+
+<C storage class> ::=
+ auto
+ | extern
+ | static
+
+<C class modifier> ::= const | volatile
+
+<C variable specification> ::=
+ <C numeric variable>
+ | <C character variable>
+ | <C derived variable>
+
+<C numeric variable> ::=
+ { long | short | float | double }
+ <C host identifier> [ <C initial value> ]
+ [ { <comma> <C host identifier> [ <C initial value> ] }... ]
+
+<C initial value> ::=
+ <equals operator> <character representation>...
+
+<C character variable> ::=
+ char [ CHARACTER SET
+ [ IS ] <character set specification> ]
+ <C host identifier>
+ <C array specification> [ <C initial value> ]
+ [ { <comma> <C host identifier>
+ <C array specification>
+ [ <C initial value> ] }... ]
+
+<C array specification> ::=
+ <left bracket> <length> <right bracket>
+
+<C derived variable> ::=
+ <C VARCHAR variable>
+ | <C bit variable>
+
+<C VARCHAR variable> ::=
+ VARCHAR [ CHARACTER SET [ IS ]
+ <character set specification> ]
+ <C host identifier>
+ <C array specification> [ <C initial value> ]
+ [ { <comma> <C host identifier>
+ <C array specification>
+ [ <C initial value> ] }... ]
+
+<C bit variable> ::=
+ BIT <C host identifier>
+ <C array specification> [ <C initial value> ]
+ [ { <comma> <C host identifier>
+ <C array specification>
+ [ <C initial value> ] }... ]
+
+<COBOL variable definition> ::=
+ {01|77} <COBOL host identifier> <COBOL type specification>
+ [ <character representation>... ] <period>
+
+<COBOL type specification> ::=
+ <COBOL character type>
+ | <COBOL bit type>
+ | <COBOL numeric type>
+ | <COBOL integer type>
+
+<COBOL character type> ::=
+ [ CHARACTER SET [ IS ]
+ <character set specification> ]
+ { PIC | PICTURE } [ IS ] { X [ <left paren> <length> <right paren> ] }...
+
+<COBOL bit type> ::=
+ { PIC | PICTURE } [ IS ]
+ { B [ <left paren> <length> <right paren> ] }...
+
+<COBOL numeric type> ::=
+ { PIC | PICTURE } [ IS ]
+ S <COBOL nines specification>
+ [ USAGE [ IS ] ] DISPLAY SIGN LEADING SEPARATE
+
+<COBOL nines specification> ::=
+ <COBOL nines> [ V [ <COBOL nines> ] ]
+ | V <COBOL nines>
+
+<COBOL nines> ::= { 9 [ <left paren> <length> <right paren> ] }...
+
+<COBOL integer type> ::=
+ <COBOL computational integer>
+ | <COBOL binary integer>
+
+<COBOL computational integer> ::=
+ { PIC | PICTURE } [ IS ] S<COBOL nines>
+ [ USAGE [ IS ] ] { COMP | COMPUTATIONAL }
+
+<COBOL binary integer> ::=
+ { PIC | PICTURE } [ IS ] S<COBOL nines>
+ [ USAGE [ IS ] ] BINARY
+
+<Fortran variable definition> ::=
+ <Fortran type specification>
+ <Fortran host identifier>
+ [ { <comma> <Fortran host identifier> }... ]
+
+<Fortran type specification> ::=
+ CHARACTER [ <asterisk> <length> ]
+ [ CHARACTER SET [ IS ]
+ <character set specification> ]
+ | BIT [ <asterisk> <length> ]
+ | INTEGER
+ | REAL
+ | DOUBLE PRECISION
+
+<MUMPS variable definition> ::=
+ { <MUMPS numeric variable> | <MUMPS character variable> }
+ <semicolon>
+
+<MUMPS numeric variable> ::=
+ <MUMPS type specification>
+ <MUMPS host identifier> [ { <comma> <MUMPS host identifier> }... ]
+
+<MUMPS type specification> ::=
+ INT
+ | DEC
+ [ <left paren> <precision> [ <comma> <scale> ] <right paren> ]
+ | REAL
+
+<MUMPS character variable> ::=
+ VARCHAR <MUMPS host identifier> <MUMPS length specification>
+ [ { <comma> <MUMPS host identifier> <MUMPS length specification> }... ]
+
+<MUMPS length specification> ::=
+ <left paren> <length> <right paren>
+
+<Pascal variable definition> ::=
+ <Pascal host identifier> [ { <comma> <Pascal host identifier> }... ] <colon>
+ <Pascal type specification> <semicolon>
+
+<Pascal type specification> ::=
+ PACKED ARRAY
+ <left bracket> 1 <double period> <length> <right bracket>
+ OF CHAR
+ [ CHARACTER SET [ IS ]
+ <character set specification> ]
+ | PACKED ARRAY
+ <left bracket> 1 <double period> <length> <right bracket>
+ OF BIT
+ | INTEGER
+ | REAL
+ | CHAR [ CHARACTER SET
+ [ IS ] <character set specification> ]
+ | BIT
+
+<PL/I variable definition> ::=
+ {DCL | DECLARE}
+ { <PL/I host identifier>
+ | <left paren> <PL/I host identifier>
+ [ { <comma> <PL/I host identifier> }... ] <right paren> }
+ <PL/I type specification>
+ [ <character representation>... ] <semicolon>
+
+<PL/I type specification> ::=
+ { CHAR | CHARACTER } [ VARYING ]
+ <left paren><length><right paren>
+ [ CHARACTER SET
+ [ IS ] <character set specification> ]
+ | BIT [ VARYING ] <left paren><length><right paren>
+ | <PL/I type fixed decimal> <left paren> <precision>
+ [ <comma> <scale> ] <right paren>
+ | <PL/I type fixed binary> [ <left paren> <precision> <right paren> ]
+ | <PL/I type float binary> <left paren> <precision> <right paren>
+
+<PL/I type fixed decimal> ::=
+ { DEC | DECIMAL } FIXED
+ | FIXED { DEC | DECIMAL }
+
+<PL/I type fixed binary> ::=
+ { BIN | BINARY } FIXED
+ | FIXED { BIN | BINARY }
+
+<PL/I type float binary> ::=
+ { BIN | BINARY } FLOAT
+ | FLOAT { BIN | BINARY }
+
+<embedded SQL end declare> ::=
+ <SQL prefix> END DECLARE SECTION
+ [ <SQL terminator> ]
+
+<embedded SQL MUMPS declare> ::=
+ <SQL prefix>
+ BEGIN DECLARE SECTION
+ [ <embedded character set declaration> ]
+ [ <host variable definition>... ]
+ END DECLARE SECTION
+ <SQL terminator>
+
+<embedded SQL statement> ::=
+ <SQL prefix>
+ <statement or declaration>
+ [ <SQL terminator> ]
+
+<statement or declaration> ::=
+ <declare cursor>
+ | <dynamic declare cursor>
+ | <temporary table declaration>
+ | <embedded exception declaration>
+ | <SQL procedure statement>
+
+<embedded exception declaration> ::=
+ WHENEVER <condition> <condition action>
+
+<condition> ::=
+ SQLERROR | NOT FOUND
+
+<condition action> ::=
+ CONTINUE | <go to>
+
+<go to> ::=
+ { GOTO | GO TO } <goto target>
+
+<goto target> ::=
+ <host label identifier>
+ | <unsigned integer>
+ | <host PL/I label variable>
+
+<host label identifier> ::= !!<EMPHASIS>(See the Syntax Rules.)
+
+<host PL/I label variable> ::= !!<EMPHASIS>(See the Syntax Rules.)
+
+<preparable statement> ::=
+ <preparable SQL data statement>
+ | <preparable SQL schema statement>
+ | <preparable SQL transaction statement>
+ | <preparable SQL session statement>
+ | <preparable implementation-defined statement>
+
+<preparable SQL data statement> ::=
+ <delete statement: searched>
+ | <dynamic single row select statement>
+ | <insert statement>
+ | <dynamic select statement>
+ | <update statement: searched>
+ | <preparable dynamic delete statement: positioned>
+ | <preparable dynamic update statement: positioned>
+
+<dynamic single row select statement> ::= <query specification>
+
+<dynamic select statement> ::= <cursor specification>
+
+<preparable dynamic delete statement: positioned> ::=
+ DELETE [ FROM <table name> ]
+ WHERE CURRENT OF <cursor name>
+
+<preparable dynamic update statement: positioned> ::=
+ UPDATE [ <table name> ]
+ SET <set clause list>
+ WHERE CURRENT OF <cursor name>
+
+<preparable SQL schema statement> ::=
+ <SQL schema statement>
+
+<preparable SQL transaction statement> ::=
+ <SQL transaction statement>
+
+<preparable SQL session statement> ::=
+ <SQL session statement>
+
+<preparable implementation-defined statement> ::=
+ !! <EMPHASIS>(See the Syntax Rules.)
+
+<direct SQL statement> ::=
+ <directly executable statement> <semicolon>
+
+<directly executable statement> ::=
+ <direct SQL data statement>
+ | <SQL schema statement>
+ | <SQL transaction statement>
+ | <SQL connection statement>
+ | <SQL session statement>
+ | <direct implementation-defined statement>
+
+<direct SQL data statement> ::=
+ <delete statement: searched>
+ | <direct select statement: multiple rows>
+ | <insert statement>
+ | <update statement: searched>
+ | <temporary table declaration>
+
+<direct select statement: multiple rows> ::=
+ <query expression> [ <order by clause> ]
+
+<direct implementation-defined statement> ::=
+ !!<EMPHASIS>(See the Syntax Rules)
+
+<SQL object identifier> ::=
+ <SQL provenance> <SQL variant>
+
+<SQL provenance> ::= <arc1> <arc2> <arc3>
+
+<arc1> ::= iso | 1 | iso <left paren> 1 <right paren>
+
+<arc2> ::= standard | 0 | standard <left paren> 0 <right paren>
+
+<arc3> ::= 9075
+
+<SQL variant> ::= <SQL edition> <SQL conformance>
+
+<SQL edition> ::= <1987> | <1989> | <1992>
+
+<1987> ::= 0 | edition1987 <left paren> 0 <right paren>
+
+<1989> ::= <1989 base> <1989 package>
+
+<1989 base> ::= 1 | edition1989 <left paren> 1 <right paren>
+
+<1989 package> ::= <integrity no> | <integrity yes>
+
+<integrity no> ::= 0 | IntegrityNo <left paren> 0 <right paren>
+
+<integrity yes> ::= 1 | IntegrityYes <left paren> 1 <right paren>
+
+<1992> ::= 2 | edition1992 <left paren> 2 <right paren>
+
+<SQL conformance> ::= <low> | <intermediate> | <high>
+
+<low> ::= 0 | Low <left paren> 0 <right paren>
+
+<intermediate> ::= 1 | Intermediate <left paren> 1 <right paren>
+
+<high> ::= 2 | High <left paren> 2 <right paren>
+
Property changes on: branches/ddl_sequencer/extensions/dna-sequencer-ddl/target/test-classes/sql2bnf.aug92.txt
___________________________________________________________________
Name: svn:mime-type
+ text/plain
16 years, 7 months
DNA SVN: r1279 - branches.
by dna-commits@lists.jboss.org
Author: blafond
Date: 2009-10-02 11:18:24 -0400 (Fri, 02 Oct 2009)
New Revision: 1279
Added:
branches/ddl_sequencer/
Log:
Copied: branches/ddl_sequencer (from rev 1278, trunk)
16 years, 7 months