All Downloads are FREE. Search and download functionalities are using the official Maven repository.
Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
studio.raptor.sqlparser.fast.expression.CompareLike Maven / Gradle / Ivy
/*
* Copyright 2004-2014 H2 Group. Multiple-Licensed under the MPL 2.0,
* and the EPL 1.0 (http://h2database.com/html/license.html).
* Initial Developer: H2 Group
*/
package studio.raptor.sqlparser.fast.expression;
import java.util.regex.Pattern;
import studio.raptor.sqlparser.fast.message.ParseException;
import studio.raptor.sqlparser.fast.value.Value;
import studio.raptor.sqlparser.fast.table.ColumnResolver;
/**
* Pattern matching comparison expression: WHERE NAME LIKE ?
*/
public class CompareLike extends Condition {
private static final int MATCH = 0, ONE = 1, ANY = 2;
private final boolean regexp;
private Expression left;
private Expression right;
private Expression escape;
private boolean isInit;
private char[] patternChars;
private String patternString;
/**
* one of MATCH / ONE / ANY
*/
private int[] patternTypes;
private int patternLength;
private Pattern patternRegexp;
private boolean ignoreCase;
private boolean fastCompare;
private boolean invalidPattern;
/**
* indicates that we can shortcut the comparison and use startsWith
*/
private boolean shortcutToStartsWith;
/**
* indicates that we can shortcut the comparison and use endsWith
*/
private boolean shortcutToEndsWith;
/**
* indicates that we can shortcut the comparison and use contains
*/
private boolean shortcutToContains;
public CompareLike(
Expression left, Expression right, Expression escape, boolean regexp) {
this.regexp = regexp;
this.left = left;
this.right = right;
this.escape = escape;
}
@Override
public Value getValue() {
return null;
}
private static Character getEscapeChar(String s) {
return s == null || s.length() == 0 ? null : s.charAt(0);
}
private static boolean containsIgnoreCase(String src, String what) {
final int length = what.length();
if (length == 0) {
// Empty string is contained
return true;
}
final char firstLo = Character.toLowerCase(what.charAt(0));
final char firstUp = Character.toUpperCase(what.charAt(0));
for (int i = src.length() - length; i >= 0; i--) {
// Quick check before calling the more expensive regionMatches()
final char ch = src.charAt(i);
if (ch != firstLo && ch != firstUp) {
continue;
}
if (src.regionMatches(true, i, what, 0, length)) {
return true;
}
}
return false;
}
@Override
public String getSQL() {
String sql;
if (regexp) {
sql = left.getSQL() + " REGEXP " + right.getSQL();
} else {
sql = left.getSQL() + " LIKE " + right.getSQL();
if (escape != null) {
sql += " ESCAPE " + escape.getSQL();
}
}
return "(" + sql + ")";
}
@Override
public Expression optimize() {
return null;
}
private boolean compareAt(String s, int pi, int si, int sLen,
char[] pattern, int[] types) {
for (; pi < patternLength; pi++) {
switch (types[pi]) {
case MATCH:
if ((si >= sLen) || !compare(pattern, s, pi, si++)) {
return false;
}
break;
case ONE:
if (si++ >= sLen) {
return false;
}
break;
case ANY:
if (++pi >= patternLength) {
return true;
}
while (si < sLen) {
if (compare(pattern, s, pi, si) &&
compareAt(s, pi, si, sLen, pattern, types)) {
return true;
}
si++;
}
return false;
default:
ParseException.throwInternalError("" + types[pi]);
}
}
return si == sLen;
}
private boolean compare(char[] pattern, String s, int pi, int si) {
return pattern[pi] == s.charAt(si);
}
/**
* Test if the value matches the pattern.
*
* @param testPattern the pattern
* @param value the value
* @param escapeChar the escape character
* @return true if the value matches
*/
public boolean test(String testPattern, String value, char escapeChar) {
initPattern(testPattern, escapeChar);
if (invalidPattern) {
return false;
}
return compareAt(value, 0, 0, value.length(), patternChars, patternTypes);
}
private void initPattern(String p, Character escapeChar) {
}
private boolean isFullMatch() {
if (patternTypes == null) {
return false;
}
for (int type : patternTypes) {
if (type != MATCH) {
return false;
}
}
return true;
}
@Override
public void mapColumns(ColumnResolver resolver, int level) {
left.mapColumns(resolver, level);
right.mapColumns(resolver, level);
if (escape != null) {
escape.mapColumns(resolver, level);
}
}
@Override
public boolean isEverything(ExpressionVisitor visitor) {
return left.isEverything(visitor) && right.isEverything(visitor)
&& (escape == null || escape.isEverything(visitor));
}
@Override
public int getType() {
return 0;
}
}