📄 like.java
字号:
int m=0; for (int l = pStart; l<pEnd; ) { if (haveEsc && matchSpecial(pattern, l, pEnd, escCharInts)) { l += escCharInts.length + 1; m += escCharInts.length; } else if (matchSpecial(pattern, l, pEnd, anyStringInts)) { l += anyStringInts.length; // anyString, nothing needed } else { // anyChar or other chars, need one char l++; m++; } } return m; } /** * checkLengths -- non-national chars * * Returns null if we are not done. * Returns true if we are at the end of our value and pattern * Returns false if there is more pattern left but out of input value * * @param vLoc current index into char[] val * @param vEnd end index or our value * @param pLoc current index into our char[] pattern * @param pat pattern char [] * @param pEnd end index of our pattern [] */ static Boolean checkLengths(int vLoc, int vEnd, int pLoc, char[] pat, int pEnd) { if (vLoc == vEnd) { if (pLoc == pEnd) { return Boolean.TRUE; } else { // if remainder of pattern is anyString chars, ok for (int i=pLoc; i<pEnd; i++) { if (pat[i] != anyString) { return Boolean.FALSE; // more to match } } return Boolean.TRUE; } } else if (pLoc == pEnd) { return Boolean.FALSE; // ran out of pattern } else return null; // still have strings to match, not done } /** * checkLengths -- national chars * * Returns null if we are not done. * Returns true if we are at the end of our value and pattern * Returns false if there is more pattern left but out of input value * * @param vLoc current index into int[] val * @param vEnd end index or our value * @param pLoc current index into our int[] pattern * @param pat pattern int [] * @param pEnd end index of our pattern [] */ static Boolean checkLengths(int vLoc, int vEnd, int pLoc, int[] pat, int pEnd, int[] anyStringInts) { if (vLoc == vEnd) { if (pLoc == pEnd) { return Boolean.TRUE; } else { // if remainder of pattern is anyString chars, ok for (int i=pLoc; i<pEnd; i += anyStringInts.length) { if (! matchSpecial(pat, i, pEnd, anyStringInts)) { return Boolean.FALSE; } } return Boolean.TRUE; } } else if (pLoc == pEnd) { return Boolean.FALSE; // ran out of pattern } else return null; // still have strings to match, not done } /** * matchSpecial * * check the pattern against the various special character arrays. * The array can be anyStringInts, anyCharInts or anyEscChars (always 1) */ private static boolean matchSpecial(int[] pat, int patStart, int patEnd, int[] specialInts) { // // multi-collation units per char can exceed the pattern length // and we fall around the 2nd if statement and falsely return true. // if (specialInts.length > patEnd - patStart) return false; if (specialInts.length <= patEnd - patStart) { for (int index = 0; index < specialInts.length; index++) { if (pat[patStart + index] != specialInts[index]) { return false; // more to match } } } return true; } /* Most typical interface for non-national chars */ public static Boolean like(char[] value, int valueLength, char[] pattern, int patternLength) throws StandardException { if (value == null || pattern == null) return null; return like(value, valueLength, pattern, patternLength, null, 0); } /* Most typical interface for national chars */ public static Boolean like(int[] value, int valueLength, int[] pattern, int patternLength, RuleBasedCollator collator) throws StandardException { if (value == null || pattern == null) return null; return like(value, valueLength, pattern, patternLength, null, 0, collator); } // Methods for LIKE transformation at preprocess time: /** * Determine whether or not this LIKE can be transformed into optimizable * clauses. It can if the pattern is non-null, of length > 0 and * the first character is not a wild card. * * @param pattern The right side of the LIKE * * @return Whether or not the LIKE can be transformed */ public static boolean isOptimizable(String pattern) { if (pattern == null || (pattern.length() == 0)) { return false; } // if we have pattern matching at start of string, no optimization char firstChar = pattern.charAt(0); return (firstChar != anyChar && firstChar != anyString); } public static String greaterEqualStringFromParameter(String pattern, int maxWidth) throws StandardException { if (pattern == null) return null; return greaterEqualString(pattern, (String) null, maxWidth); } public static String greaterEqualStringFromParameterWithEsc(String pattern, String escape, int maxWidth) throws StandardException { if (pattern == null) return null; return greaterEqualString(pattern, escape, maxWidth); } /** * Return the substring from the pattern for the optimization >= clause. * * @param pattern The right side of the LIKE * @param escape The escape clause * @param maxWidth Maximum length of column, for null padding * * @return The String for the >= clause */ public static String greaterEqualString(String pattern, String escape, int maxWidth) throws StandardException { int firstAnyChar = pattern.indexOf(anyChar); int firstAnyString = pattern.indexOf(anyString); // // For Escape we don't utilize any of the stylish code // below but brute force walk the pattern to find out // what is there, while stripping escapes // if ((escape != null) && (escape.length() != 0)) { char escChar = escape.charAt(0); if (pattern.indexOf(escChar) != -1) { // we return a string stripping out the escape char // leaving the _? in place as normal chars. return padWithNulls(greaterEqualString(pattern, escChar), maxWidth); } // drop through if no escape found } if (firstAnyChar == -1) { if (firstAnyString != -1) // no _, found % { pattern = pattern.substring(0, firstAnyString); } } else if (firstAnyString == -1) { pattern = pattern.substring(0, firstAnyChar); } else { pattern = pattern.substring(0, (firstAnyChar > firstAnyString) ? firstAnyString : firstAnyChar); } return padWithNulls(pattern, maxWidth); } /** * greaterEqualString -- for Escape clause only * * Walk the pattern character by character * @param pattern like pattern to build from * @param escChar the escape character in the pattern */ private static String greaterEqualString(String pattern, char escChar) throws StandardException { int patternLen = pattern.length(); char[] patternChars = new char[patternLen]; char[] result = new char[patternLen]; pattern.getChars(0, patternLen, patternChars, 0); int r = 0; for (int p = 0; p < patternLen && r < patternLen; p++) { char c = patternChars[p]; if (c == escChar) { p++; // don't copy the escape char // run out? if (p >= patternLen) throw StandardException.newException( SQLState.LANG_INVALID_ESCAPE_SEQUENCE); result[r++] = patternChars[p]; continue; } // stop on first pattern matching char if (c == anyChar || c == anyString) { return new String(result, 0, r); } result[r++] = patternChars[p]; } // no pattern chars return new String(result, 0, r); } /** * stripEscapesNoPatternChars * * @param pattern pattern String to search * @param escChar the escape character * * @return a stripped of ESC char string if no pattern chars, null otherwise * @exception StandardException thrown if data invalid */ public static String stripEscapesNoPatternChars(String pattern, char escChar) throws StandardException { int patternLen = pattern.length(); char[] patternChars = new char[patternLen]; char[] result = new char[patternLen]; pattern.getChars(0, patternLen, patternChars, 0); int r = 0; for (int p = 0; p < patternLen && r < patternLen; p++) { char c = pattern.charAt(p); if (c == escChar) { p++; // don't copy the escape char // run out? if (p >= patternLen) throw StandardException.newException( SQLState.LANG_INVALID_ESCAPE_SEQUENCE); result[r++] = patternChars[p]; continue; } // die on first pattern matching char if (c == anyChar || c == anyString) { return null; } result[r++] = patternChars[p]; } return new String(result, 0, r); } public static String lessThanStringFromParameter(String pattern, int maxWidth) throws StandardException { if (pattern == null) return null; return lessThanString(pattern, null, maxWidth); } public static String lessThanStringFromParameterWithEsc(String pattern, String escape, int maxWidth) throws StandardException { if (pattern == null) return null; return lessThanString(pattern, escape, maxWidth); } /** * Return the substring from the pattern for the < clause. * (NOTE: This may be null if the pattern is an empty string.) * * @param pattern The right side of the LIKE * @param escape The escape clause * @param maxWidth Maximum length of column, for null padding * * @return The String for the < clause * @exception StandardException thrown if data invalid */ public static String lessThanString(String pattern, String escape, int maxWidth) throws StandardException { int lastUsableChar; char oldLastChar; char newLastChar; final int escChar; if (pattern.length() == 0) { // pattern is "" return null; } if ((escape != null) && (escape.length() !=0)) { escChar = escape.charAt(0); } else { // Set escape character to a value outside the char range, // so that comparison with a char always evaluates to false. escChar = -1; } /* Find the last non-wildcard character in the pattern * and increment it. In the most common case, * "asdf%" becomes "asdg". However, we need to * handle the following: * * pattern return * ------- ------ * "" null * "%..." SUPER_STRING (match against super string) * "_..." SUPER_STRING (match against super string) * "asdf%" "asdg" */ StringBuffer upperLimit = new StringBuffer(maxWidth); // Extract the string leading up to the first wildcard. for (int i = 0; i < pattern.length(); i++) { char c = pattern.charAt(i); if (c == escChar) { if (++i >= pattern.length()) { throw StandardException.newException( SQLState.LANG_INVALID_ESCAPE_SEQUENCE); } c = pattern.charAt(i); } else if (c == anyChar || c == anyString) { break; } upperLimit.append(c); } // Pattern starts with wildcard. if (upperLimit.length() == 0) { return SUPER_STRING; } // Increment the last non-wildcard character. lastUsableChar = upperLimit.length() - 1; oldLastChar = upperLimit.charAt(lastUsableChar); newLastChar = oldLastChar; newLastChar++; // Check for degenerate roll over if (newLastChar < oldLastChar) { return SUPER_STRING; } upperLimit.setCharAt(lastUsableChar, newLastChar); // Pad the string with nulls. if (upperLimit.length() < maxWidth) { upperLimit.setLength(maxWidth); } return upperLimit.toString(); } /** * Return whether or not the like comparison is still needed after * performing the like transformation on a constant string. The * comparison is not needed if the constant string is of the form: * CONSTANT% (constant followed by a trailing %) * * @param pattern The right side of the LIKE * * @return Whether or not the like comparison is still needed. */ public static boolean isLikeComparisonNeeded(String pattern) { int firstAnyChar = pattern.indexOf(anyChar); int firstAnyString = pattern.indexOf(anyString); if (SanityManager.DEBUG) { SanityManager.ASSERT(pattern.length() != 0, "pattern expected to be non-zero length"); } // if no pattern matching characters, no LIKE needed if (firstAnyChar == -1 && firstAnyString == -1) return false; /* Needed if string containts anyChar */ if (firstAnyChar != -1) { return true; } /* Needed if string contains and anyString in any place * other than the last character. */ if (firstAnyString != pattern.length() - 1) { return true; } return false; } /** * Pad a string with null characters, in order to make it > and < * comparable with SQLChar. * * @param string The string to pad * @param len Max number of characters to pad to * @returns the string padded with 0s up to the given length */ private static String padWithNulls(String string, int len) { if(string.length() >= len) return string; StringBuffer buf = new StringBuffer(len).append(string); buf.setLength(len); return buf.toString(); }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -