/** * {@inheritDoc} * * @see * org.modeshape.jcr.query.parse.BasicSqlQueryParser#parseLiteralValue(org.modeshape.common.text.TokenStream, * org.modeshape.jcr.query.model.TypeSystem) */ @Override protected Object parseLiteralValue(TokenStream tokens, TypeSystem typeSystem) { if (tokens.canConsume("TIMESTAMP")) { Position pos = tokens.previousPosition(); // This should be a timestamp represented as a single-quoted string ... String value = removeBracketsAndQuotes(tokens.consume()); TypeFactory<?> dateTimeFactory = typeSystem.getDateTimeFactory(); try { // Convert to a date and then back to a string to get canonical form ... Object dateTime = dateTimeFactory.create(value); return dateTime; // return dateTimeFactory.asString(dateTime); } catch (ValueFormatException e) { String msg = GraphI18n.expectingLiteralAndUnableToParseAsDate.text( value, pos.getLine(), pos.getColumn()); throw new ParsingException(pos, msg); } } return super.parseLiteralValue(tokens, typeSystem); }
@SuppressWarnings("unchecked") protected ConstraintChecker createChecker( final TypeSystem types, Schemata schemata, Columns columns, final DynamicOperation dynamicOperation, Operator operator, StaticOperand staticOperand) { final String expectedType = dynamicOperation.getExpectedType(); // Determine the literal value ... Object literalValue = null; if (staticOperand instanceof BindVariableName) { BindVariableName bindVariable = (BindVariableName) staticOperand; String variableName = bindVariable.getBindVariableName(); literalValue = variables.get(variableName); // may be null } else { Literal literal = (Literal) staticOperand; literalValue = literal.value(); } // Create the correct comparator ... final TypeFactory<?> typeFactory = types.getTypeFactory(expectedType); assert typeFactory != null; final Comparator<Object> comparator = (Comparator<Object>) typeFactory.getComparator(); assert comparator != null; // Create the correct operation ... final TypeFactory<?> literalFactory = types.getTypeFactory(expectedType); final Object rhs = literalFactory.create(literalValue); switch (operator) { case EQUAL_TO: return new ConstraintChecker() { @Override public boolean satisfiesConstraints(Object[] tuples) { return comparator.compare(dynamicOperation.evaluate(tuples), rhs) == 0; } }; case GREATER_THAN: return new ConstraintChecker() { @Override public boolean satisfiesConstraints(Object[] tuples) { return comparator.compare(dynamicOperation.evaluate(tuples), rhs) > 0; } }; case GREATER_THAN_OR_EQUAL_TO: return new ConstraintChecker() { @Override public boolean satisfiesConstraints(Object[] tuples) { return comparator.compare(dynamicOperation.evaluate(tuples), rhs) >= 0; } }; case LESS_THAN: return new ConstraintChecker() { @Override public boolean satisfiesConstraints(Object[] tuples) { return comparator.compare(dynamicOperation.evaluate(tuples), rhs) < 0; } }; case LESS_THAN_OR_EQUAL_TO: return new ConstraintChecker() { @Override public boolean satisfiesConstraints(Object[] tuples) { return comparator.compare(dynamicOperation.evaluate(tuples), rhs) <= 0; } }; case NOT_EQUAL_TO: return new ConstraintChecker() { @Override public boolean satisfiesConstraints(Object[] tuples) { return comparator.compare(dynamicOperation.evaluate(tuples), rhs) != 0; } }; case LIKE: // Convert the LIKE expression to a regular expression String regex = CompareStringQuery.toRegularExpression(types.asString(rhs)); final Pattern pattern = Pattern.compile(regex); return new ConstraintChecker() { @Override public boolean satisfiesConstraints(Object[] tuples) { Object tupleValue = dynamicOperation.evaluate(tuples); if (tupleValue == null) return false; String value = types.asString(tupleValue); return pattern.matcher(value).matches(); } }; } assert false; return null; }