org.modeshape.jcr
Class JcrSqlQueryParser

java.lang.Object
  extended by org.modeshape.graph.query.parse.SqlQueryParser
      extended by org.modeshape.jcr.JcrSqlQueryParser
All Implemented Interfaces:
QueryParser

public class JcrSqlQueryParser
extends SqlQueryParser

Parser for JCR-SQL queries that produces abstract query model (AQM) objects.

JCR-SQL grammar

This section defines the complete grammar for the JCR-SQL dialect supported by this parser, as defined by the JCR 1.0.1 specification. This parser actually extends the (extended) JCR-SQL2 parser, and thus allows many of the JCR-SQL2 standard and extended features, although there are several key differences:

  1. Names are not enclosed by square brackets.
  2. Criteria on scores use
    jcr:score
    as a pseudo-column.
  3. Criteria on path use
    jcr:path
    as a pseudo-column.
  4. Joins are specified with comma-separated table names in the FROM clause and join criteria in the WHERE clause.

Queries

 QueryCommand ::= Query | SetQuery
 
 SetQuery ::= Query ('UNION'|'INTERSECT'|'EXCEPT') [ALL] Query
                  { ('UNION'|'INTERSECT'|'EXCEPT') [ALL] Query }
 
 Query ::= 'SELECT' ['DISINCT'] columns
           'FROM' Source
           ['WHERE' Constraint]
           ['ORDER BY' orderings]
           [Limit]
 

Sources

 Source ::= Selector | Join
 
 Selector ::= nodeTypeName ['AS' selectorName]
 
 nodeTypeName ::= Name
 

Joins

 Join ::= left [JoinType] 'JOIN' right 'ON' JoinCondition
          // If JoinType is omitted INNER is assumed.
          
 left ::= Source
 right ::= Source
 
 JoinType ::= Inner | LeftOuter | RightOuter | FullOuter | Cross
 
 Inner ::= 'INNER' ['JOIN']
 
 LeftOuter ::= 'LEFT JOIN' | 'OUTER JOIN' | 'LEFT OUTER JOIN'
 
 RightOuter ::= 'RIGHT OUTER' ['JOIN']
 
 RightOuter ::= 'FULL OUTER' ['JOIN']
 
 RightOuter ::= 'CROSS' ['JOIN']
 
 JoinCondition ::= EquiJoinCondition | SameNodeJoinCondition | ChildNodeJoinCondition | DescendantNodeJoinCondition
 
Equi-join conditions
 EquiJoinCondition ::= selector1Name'.'property1Name '=' selector2Name'.'property2Name
 
 selector1Name ::= selectorName
 selector2Name ::= selectorName
 property1Name ::= propertyName
 property2Name ::= propertyName
 
Same-node join condition
 SameNodeJoinCondition ::= 'ISSAMENODE(' selector1Name ',' selector2Name [',' selector2Path] ')'
 
 selector2Path ::= Path
 
Child-node join condition
 ChildNodeJoinCondition ::= 'ISCHILDNODE(' childSelectorName ',' parentSelectorName ')'
 
 childSelectorName ::= selectorName
 parentSelectorName ::= selectorName
 
Descendant-node join condition
 DescendantNodeJoinCondition ::= 'ISDESCENDANTNODE(' descendantSelectorName ',' ancestorSelectorName ')'
 descendantSelectorName ::= selectorName
 ancestorSelectorName ::= selectorName
 

Constraints

 Constraint ::= ConstraintItem | '(' ConstraintItem ')'
 
 ConstraintItem ::= And | Or | Not | Comparison | Between | PropertyExistence | SetConstraint | FullTextSearch | 
                    SameNode | ChildNode | DescendantNode
 
And constraint
 And ::= constraint1 'AND' constraint2
 
 constraint1 ::= Constraint
 constraint2 ::= Constraint
 
Or constraint
 Or ::= constraint1 'OR' constraint2
 
Not constraint
 Not ::= 'NOT' Constraint
 
Comparison constraint
 Comparison ::= DynamicOperand Operator StaticOperand
 
 Operator ::= '=' | '!=' | '<' | '<=' | '>' | '>=' | 'LIKE'
 
Between constraint
 Between ::= DynamicOperand ['NOT'] 'BETWEEN' lowerBound ['EXCLUSIVE'] 'AND' upperBound ['EXCLUSIVE']
 
 lowerBound ::= StaticOperand
 upperBound ::= StaticOperand
 
Property existence constraint
 PropertyExistence ::= selectorName'.'propertyName 'IS' ['NOT'] 'NULL' | 
                       propertyName 'IS' ['NOT'] 'NULL' /* If only one selector exists in this query */
 
 
Set constraint
 SetConstraint ::= selectorName'.'propertyName ['NOT'] 'IN' | 
                       propertyName ['NOT'] 'IN' /* If only one selector exists in this query */
                       '(' firstStaticOperand {',' additionalStaticOperand } ')'
 firstStaticOperand ::= StaticOperand
 additionalStaticOperand ::= StaticOperand
 
Full-text search constraint
 FullTextSearch ::= 'CONTAINS(' ([selectorName'.']propertyName | selectorName'.*') 
                            ',' ''' fullTextSearchExpression''' ')'
                    /* If only one selector exists in this query, explicit specification of the selectorName
                       preceding the propertyName is optional */
 fullTextSearchExpression ::= /* a full-text search expression, see FullTextSearchParser */
 
Same-node constraint
 SameNode ::= 'ISSAMENODE(' [selectorName ','] Path ')' 
                    /* If only one selector exists in this query, explicit specification of the selectorName
                       preceding the propertyName is optional */
 
Child-node constraint
 ChildNode ::= 'ISCHILDNODE(' [selectorName ','] Path ')' 
                    /* If only one selector exists in this query, explicit specification of the selectorName
                       preceding the propertyName is optional */
 
Descendant-node constraint
 DescendantNode ::= 'ISDESCENDANTNODE(' [selectorName ','] Path ')' 
                    /* If only one selector exists in this query, explicit specification of the selectorName
                       preceding the propertyName is optional */
 
Paths and names
 
 Name ::= '[' quotedName ']' | '[' simpleName ']' | simpleName
 
 quotedName ::= /* A JCR Name (see the JCR specification) */
 simpleName ::= /* A JCR Name that contains only SQL-legal characters (namely letters, digits, and underscore) */

 Path ::= '[' quotedPath ']' | '[' simplePath ']' | simplePath

 quotedPath ::= /* A JCR Path that contains non-SQL-legal characters */
 simplePath ::= /* A JCR Path (rather Name) that contains only SQL-legal characters (namely letters, digits, and underscore) */
 

Static operands

 StaticOperand ::= Literal | BindVariableValue
 
Literal
 Literal ::= CastLiteral | UncastLiteral
 
 CastLiteral ::= 'CAST(' UncastLiteral ' AS ' PropertyType ')'
 
 PropertyType ::= 'STRING' | 'BINARY' | 'DATE' | 'LONG' | 'DOUBLE' | 'DECIMAL' | 'BOOLEAN' | 'NAME' | 'PATH' | 
                  'REFERENCE' | 'WEAKREFERENCE' | 'URI'
                  /* 'WEAKREFERENCE' is not currently supported in JCR 1.0 */
                  
 UncastLiteral ::= UnquotedLiteral | ''' UnquotedLiteral ''' | '"' UnquotedLiteral '"'
 
 UnquotedLiteral ::= /* String form of a JCR Value, as defined in the JCR specification */
 
Bind variables
 BindVariableValue ::= '$'bindVariableName
 
 bindVariableName ::= /* A string that conforms to the JCR Name syntax, though the prefix does not need to be
                         a registered namespace prefix. */
 

Dynamic operands

 DynamicOperand ::= PropertyValue | ReferenceValue | Length | NodeName | NodeLocalName | NodePath | NodeDepth | 
                    FullTextSearchScore | LowerCase | UpperCase | Arithmetic |
                    '(' DynamicOperand ')'
 
Property value
 PropertyValue ::= [selectorName'.'] propertyName
                    /* If only one selector exists in this query, explicit specification of the selectorName
                       preceding the propertyName is optional */
 
Reference value
 ReferenceValue ::= 'REFERENCE(' selectorName '.' propertyName ')' |
                    'REFERENCE(' selectorName ')' |
                    'REFERENCE()' |
                    /* If only one selector exists in this query, explicit specification of the selectorName
                       preceding the propertyName is optional. Also, the property name may be excluded 
                       if the constraint should apply to any reference property. */
 
Property length
 Length ::= 'LENGTH(' PropertyValue ')'
 
Node name
 NodeName ::= 'NAME(' [selectorName] ')'
                    /* If only one selector exists in this query, explicit specification of the selectorName
                       is optional */
 
Node local name
 NodeLocalName ::= 'LOCALNAME(' [selectorName] ')'
                    /* If only one selector exists in this query, explicit specification of the selectorName
                       is optional */
 
Node path
 NodePath ::= 'PATH(' [selectorName] ')'
                    /* If only one selector exists in this query, explicit specification of the selectorName
                       is optional */
 
Node depth
 NodeDepth ::= 'DEPTH(' [selectorName] ')'
                    /* If only one selector exists in this query, explicit specification of the selectorName
                       is optional */
 
Full-text search score
 FullTextSearchScore ::= 'SCORE(' [selectorName] ')'
                    /* If only one selector exists in this query, explicit specification of the selectorName
                       is optional */
 
Lowercase
 LowerCase ::= 'LOWER(' DynamicOperand ')'
 
Uppercase
 UpperCase ::= 'UPPER(' DynamicOperand ')'
 
Arithmetic
 Arithmetic ::= DynamicOperand ('+'|'-'|'*'|'/') DynamicOperand
 

Ordering

 orderings ::= Ordering {',' Ordering}
 
 Ordering ::= DynamicOperand [Order]
 
 Order ::= 'ASC' | 'DESC'
 

Columns

 columns ::= (Column ',' {Column}) | '*'
 
 Column ::= ([selectorName'.']propertyName ['AS' columnName]) | (selectorName'.*')
                    /* If only one selector exists in this query, explicit specification of the selectorName
                       preceding the propertyName is optional */
 selectorName ::= Name
 propertyName ::= Name
 columnName ::= Name
 

Limit

 Limit ::= 'LIMIT' count [ 'OFFSET' offset ]
 count ::= /* Positive integer value */
 offset ::= /* Non-negative integer value */
 


Nested Class Summary
protected static class JcrSqlQueryParser.JoinableSources
           
 
Nested classes/interfaces inherited from class org.modeshape.graph.query.parse.SqlQueryParser
SqlQueryParser.SqlTokenizer
 
Field Summary
static String LANGUAGE
           
 
Constructor Summary
JcrSqlQueryParser()
           
 
Method Summary
 String getLanguage()
          Get the name of the language that this parser is able to understand.
protected  SelectorName getSelectorNameFor(Source source)
           
protected  Constraint parseConstraint(TokenStream tokens, TypeSystem typeSystem, Source source)
          Parse a constraint clause.
protected  Source parseFrom(TokenStream tokens, TypeSystem typeSystem)
          
protected  String parseLiteralValue(TokenStream tokens, TypeSystem typeSystem)
          
protected  String parseName(TokenStream tokens, TypeSystem typeSystem)
           Parsing behavior is overridden to that JCR-SQL style (unquoted prefixed) names are allowed.
protected  Constraint parsePropertyExistance(TokenStream tokens, TypeSystem typeSystem, Source source)
           
protected  Query parseQuery(TokenStream tokens, TypeSystem typeSystem)
          
protected  String removeBracketsAndQuotes(String text)
          Remove any leading and trailing single-quotes.
protected  Source rewrite(JcrSqlQueryParser.JoinableSources joinableSources)
           
protected  Constraint rewriteConstraint(Constraint constraint)
           
protected  boolean usesSelector(Join join, SelectorName selector)
           
 
Methods inherited from class org.modeshape.graph.query.parse.SqlQueryParser
equals, parseComparisonOperator, parseDynamicOperand, parseFullTextSearchExpression, parseInClause, parseJoinCondition, parseLimit, parseLiteral, parseNamedSelector, parseOrderBy, parseOrdering, parsePath, parsePropertyValue, parseQuery, parseQueryCommand, parseReferenceValue, parseSelect, parseSelectorName, parseSetQuery, parseStaticOperand, parseWhere, toString
 
Methods inherited from class java.lang.Object
clone, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait
 

Field Detail

LANGUAGE

public static final String LANGUAGE
See Also:
Constant Field Values
Constructor Detail

JcrSqlQueryParser

public JcrSqlQueryParser()
Method Detail

getLanguage

public String getLanguage()
Get the name of the language that this parser is able to understand.

Specified by:
getLanguage in interface QueryParser
Overrides:
getLanguage in class SqlQueryParser
Returns:
the language name; never null
See Also:
QueryParser.getLanguage()

parseQuery

protected Query parseQuery(TokenStream tokens,
                           TypeSystem typeSystem)

Overrides:
parseQuery in class SqlQueryParser
See Also:
SqlQueryParser.parseQuery(org.modeshape.common.text.TokenStream, org.modeshape.graph.query.model.TypeSystem)

parseFrom

protected Source parseFrom(TokenStream tokens,
                           TypeSystem typeSystem)

Overrides:
parseFrom in class SqlQueryParser
See Also:
SqlQueryParser.parseFrom(org.modeshape.common.text.TokenStream, org.modeshape.graph.query.model.TypeSystem)

parseConstraint

protected Constraint parseConstraint(TokenStream tokens,
                                     TypeSystem typeSystem,
                                     Source source)
Parse a constraint clause. This method inherits all of the functionality from JCR-SQL2, except that JCR-SQL allows constraints that use "jcr:path" and "jcr:score" pseudo-columns. In these special cases, the resulting comparison will have a NodePath or FullTextSearchScore dynamic operand.

Overrides:
parseConstraint in class SqlQueryParser
See Also:
SqlQueryParser.parseConstraint(org.modeshape.common.text.TokenStream, org.modeshape.graph.query.model.TypeSystem, org.modeshape.graph.query.model.Source)

parsePropertyExistance

protected Constraint parsePropertyExistance(TokenStream tokens,
                                            TypeSystem typeSystem,
                                            Source source)
Overrides:
parsePropertyExistance in class SqlQueryParser

getSelectorNameFor

protected SelectorName getSelectorNameFor(Source source)

rewriteConstraint

protected Constraint rewriteConstraint(Constraint constraint)

parseName

protected String parseName(TokenStream tokens,
                           TypeSystem typeSystem)

Parsing behavior is overridden to that JCR-SQL style (unquoted prefixed) names are allowed. This method parses the selector name, which may be of the form "unprefixedName" (consisting of a single token) or "prefix:name" (consisting of three tokens).

Overrides:
parseName in class SqlQueryParser
See Also:
SqlQueryParser.parseName(org.modeshape.common.text.TokenStream, org.modeshape.graph.query.model.TypeSystem)

parseLiteralValue

protected String parseLiteralValue(TokenStream tokens,
                                   TypeSystem typeSystem)

Overrides:
parseLiteralValue in class SqlQueryParser
See Also:
SqlQueryParser.parseLiteralValue(org.modeshape.common.text.TokenStream, org.modeshape.graph.query.model.TypeSystem)

removeBracketsAndQuotes

protected String removeBracketsAndQuotes(String text)
Remove any leading and trailing single-quotes.

Overrides:
removeBracketsAndQuotes in class SqlQueryParser
Parameters:
text - the input text; may not be null
Returns:
the text without leading and trailing quotes, or text if there were no quotes

rewrite

protected Source rewrite(JcrSqlQueryParser.JoinableSources joinableSources)

usesSelector

protected boolean usesSelector(Join join,
                               SelectorName selector)


Copyright © 2008-2010 JBoss, a division of Red Hat. All Rights Reserved.