improve SQL Eval support

This commit is contained in:
wenshao
2013-03-30 23:05:08 +08:00
parent 54e3ec9323
commit 275e4b68b7
50 changed files with 1163 additions and 51 deletions
@@ -70,12 +70,9 @@ public enum SQLBinaryOperator {
BooleanOr("OR", 160),
Assignment(":=", 169),
PostgresStyleTypeCast("::", 20),
;
public static int getPriority(SQLBinaryOperator operator) {
return 0;
}
@@ -323,12 +323,12 @@ public class MySqlExprParser extends SQLExprParser {
} else if (lexer.token() == Token.FROM) {
lexer.nextToken();
SQLExpr from = expr();
methodInvokeExpr.putAttribute("FROM", from);
methodInvokeExpr.getParameters().add(from);
if (lexer.token() == Token.FOR) {
lexer.nextToken();
SQLExpr forExpr = expr();
methodInvokeExpr.putAttribute("FOR", forExpr);
methodInvokeExpr.getParameters().add(forExpr);
}
break;
} else if (lexer.token() == Token.RPAREN) {
@@ -15,6 +15,9 @@
*/
package com.alibaba.druid.sql.dialect.postgresql.parser;
import com.alibaba.druid.sql.ast.SQLExpr;
import com.alibaba.druid.sql.ast.expr.SQLBinaryOpExpr;
import com.alibaba.druid.sql.ast.expr.SQLBinaryOperator;
import com.alibaba.druid.sql.dialect.postgresql.ast.PGOrderBy;
import com.alibaba.druid.sql.parser.Lexer;
import com.alibaba.druid.sql.parser.SQLExprParser;
@@ -68,4 +71,16 @@ public class PGExprParser extends SQLExprParser {
return null;
}
public SQLExpr primaryRest(SQLExpr expr) {
if (lexer.token() == Token.COLONCOLON) {
lexer.nextToken();
SQLExpr typeExpr = this.expr();
SQLBinaryOpExpr castExpr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.PostgresStyleTypeCast, typeExpr);
return primaryRest(castExpr);
}
return super.primaryRest(expr);
}
}
@@ -20,6 +20,7 @@ import static com.alibaba.druid.sql.parser.CharTypes.isIdentifierChar;
import static com.alibaba.druid.sql.parser.CharTypes.isWhitespace;
import static com.alibaba.druid.sql.parser.LayoutCharacters.EOI;
import static com.alibaba.druid.sql.parser.Token.COLONEQ;
import static com.alibaba.druid.sql.parser.Token.COLONCOLON;
import static com.alibaba.druid.sql.parser.Token.COMMA;
import static com.alibaba.druid.sql.parser.Token.EOF;
import static com.alibaba.druid.sql.parser.Token.ERROR;
@@ -41,31 +42,31 @@ import java.util.Arrays;
*/
public class Lexer {
protected final String text;
protected int pos;
protected int mark;
protected final String text;
protected int pos;
protected int mark;
protected char ch;
protected char ch;
protected char[] buf;
protected int bufPos;
protected char[] buf;
protected int bufPos;
protected Token token;
protected Token token;
protected Keywords keywods = Keywords.DEFAULT_KEYWORDS;
protected Keywords keywods = Keywords.DEFAULT_KEYWORDS;
protected String stringVal;
protected String stringVal;
protected boolean skipComment = true;
protected boolean skipComment = true;
private SavePoint savePoint = null;
private SavePoint savePoint = null;
/*
* anti sql injection
*/
private boolean allowComment = true;
private boolean allowComment = true;
private int varIndex = -1;
private int varIndex = -1;
public Lexer(String input){
this(input, true);
@@ -78,7 +79,7 @@ public class Lexer {
return text.charAt(index);
}
public final String addSymbol() {
return subString(mark, bufPos);
}
@@ -86,7 +87,7 @@ public class Lexer {
public final String subString(int offset, int count) {
return text.substring(offset, offset + count);
}
protected void initBuff(int size) {
if (buf == null) {
if (size < 32) {
@@ -94,7 +95,7 @@ public class Lexer {
} else {
buf = new char[size + 32];
}
} else if(buf.length < size) {
} else if (buf.length < size) {
buf = Arrays.copyOf(buf, size);
}
}
@@ -116,6 +117,7 @@ public class Lexer {
}
private static class SavePoint {
int bp;
int sp;
int np;
@@ -187,32 +189,32 @@ public class Lexer {
public String info() {
return this.token + " " + this.stringVal();
}
public final void nextTokenComma() {
if (ch == ' ') {
scanChar();
}
if (ch == ',') {
scanChar();
token = COMMA;
return;
}
if (ch == ')') {
scanChar();
token = RPAREN;
return;
}
nextToken();
}
public final void nextTokenLParen() {
if (ch == ' ') {
scanChar();
}
if (ch == '(') {
scanChar();
token = LPAREN;
@@ -220,38 +222,38 @@ public class Lexer {
}
nextToken();
}
public final void nextTokenValue() {
if (ch == ' ') {
scanChar();
}
if (ch == '\'') {
bufPos = 0;
scanString();
return;
}
if (ch >= '0' && ch <= '9') {
bufPos = 0;
scanNumber();
return;
}
if (ch == '?') {
scanChar();
token = Token.QUES;
return;
}
if (isFirstIdentifierChar(ch) && ch != 'N') {
scanIdentifier();
return;
}
nextToken();
}
public final void nextToken() {
bufPos = 0;
@@ -334,6 +336,9 @@ public class Lexer {
if (ch == '=') {
scanChar();
token = COLONEQ;
} else if (ch == ':') {
scanChar();
token = COLONCOLON;
} else {
if (isDigit(ch)) {
unscan();
@@ -762,7 +767,6 @@ public class Lexer {
break;
}
bufPos++;
continue;
}
@@ -207,6 +207,7 @@ public enum Token {
TILDE("~"),
QUES("?"),
COLON(":"),
COLONCOLON(":"),
COLONEQ(":="),
EQEQ("=="),
LTEQ("<="),
@@ -56,16 +56,25 @@ import com.alibaba.druid.sql.dialect.oracle.visitor.OracleEvalVisitor;
import com.alibaba.druid.sql.dialect.postgresql.visitor.PGEvalVisitor;
import com.alibaba.druid.sql.dialect.sqlserver.visitor.SQLServerEvalVisitor;
import com.alibaba.druid.sql.visitor.functions.Ascii;
import com.alibaba.druid.sql.visitor.functions.Bin;
import com.alibaba.druid.sql.visitor.functions.BitLength;
import com.alibaba.druid.sql.visitor.functions.Char;
import com.alibaba.druid.sql.visitor.functions.Concat;
import com.alibaba.druid.sql.visitor.functions.Elt;
import com.alibaba.druid.sql.visitor.functions.Function;
import com.alibaba.druid.sql.visitor.functions.Hex;
import com.alibaba.druid.sql.visitor.functions.Insert;
import com.alibaba.druid.sql.visitor.functions.Instr;
import com.alibaba.druid.sql.visitor.functions.Lcase;
import com.alibaba.druid.sql.visitor.functions.Left;
import com.alibaba.druid.sql.visitor.functions.Length;
import com.alibaba.druid.sql.visitor.functions.Locate;
import com.alibaba.druid.sql.visitor.functions.Lpad;
import com.alibaba.druid.sql.visitor.functions.Ltrim;
import com.alibaba.druid.sql.visitor.functions.Now;
import com.alibaba.druid.sql.visitor.functions.Reverse;
import com.alibaba.druid.sql.visitor.functions.Right;
import com.alibaba.druid.sql.visitor.functions.Substring;
import com.alibaba.druid.sql.visitor.functions.Trim;
import com.alibaba.druid.sql.visitor.functions.Ucase;
import com.alibaba.druid.sql.visitor.functions.Unhex;
@@ -149,13 +158,26 @@ public class SQLEvalVisitorUtils {
static void registerBaseFunctions() {
functions.put("now", Now.instance);
functions.put("concat", Concat.instance);
functions.put("concat_ws", Concat.instance);
functions.put("ascii", Ascii.instance);
functions.put("bin", Bin.instance);
functions.put("bit_length", BitLength.instance);
functions.put("insert", Insert.instance);
functions.put("instr", Instr.instance);
functions.put("char", Char.instance);
functions.put("elt", Elt.instance);
functions.put("left", Left.instance);
functions.put("locate", Locate.instance);
functions.put("lpad", Lpad.instance);
functions.put("ltrim", Ltrim.instance);
functions.put("mid", Substring.instance);
functions.put("substring", Substring.instance);
functions.put("right", Right.instance);
functions.put("reverse", Reverse.instance);
functions.put("len", Length.instance);
functions.put("length", Length.instance);
functions.put("char_length", Length.instance);
functions.put("character_length", Length.instance);
functions.put("trim", Trim.instance);
functions.put("ucase", Ucase.instance);
functions.put("upper", Ucase.instance);
@@ -172,6 +194,7 @@ public class SQLEvalVisitorUtils {
if (function != null) {
Object result = function.eval(visitor, x);
if (result != SQLEvalVisitor.EVAL_ERROR) {
x.getAttributes().put(EVAL_VALUE, result);
}
@@ -721,7 +744,7 @@ public class SQLEvalVisitorUtils {
SQLExpr leftEvalExpr = (SQLExpr) left.getAttribute(EVAL_EXPR);
SQLExpr rightEvalExpr = (SQLExpr) right.getAttribute(EVAL_EXPR);
if (leftEvalExpr.equals(rightEvalExpr)) {
if (leftEvalExpr != null && leftEvalExpr.equals(rightEvalExpr)) {
switch (x.getOperator()) {
case Like:
case Equality:
@@ -562,6 +562,10 @@ public class SchemaStatVisitor extends SQLASTVisitorAdapter {
}
public boolean visit(SQLSelectQueryBlock x) {
if (x.getFrom() == null) {
return false;
}
setMode(x, Mode.Select);
if (x.getFrom() instanceof SQLSubqueryTableSource) {
@@ -0,0 +1,48 @@
/*
* Copyright 1999-2011 Alibaba Group Holding Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.alibaba.druid.sql.visitor.functions;
import static com.alibaba.druid.sql.visitor.SQLEvalVisitor.EVAL_VALUE;
import com.alibaba.druid.sql.ast.SQLExpr;
import com.alibaba.druid.sql.ast.expr.SQLMethodInvokeExpr;
import com.alibaba.druid.sql.visitor.SQLEvalVisitor;
public class Bin implements Function {
public final static Bin instance = new Bin();
public Object eval(SQLEvalVisitor visitor, SQLMethodInvokeExpr x) {
if (x.getParameters().size() != 1) {
return SQLEvalVisitor.EVAL_ERROR;
}
SQLExpr param0 = x.getParameters().get(0);
param0.accept(visitor);
Object param0Value = param0.getAttributes().get(EVAL_VALUE);
if (param0Value == null) {
return SQLEvalVisitor.EVAL_ERROR;
}
if (param0Value instanceof Number) {
long longValue = ((Number) param0Value).longValue();
String result = Long.toString(longValue, 2);
return result;
}
return SQLEvalVisitor.EVAL_ERROR;
}
}
@@ -0,0 +1,46 @@
/*
* Copyright 1999-2011 Alibaba Group Holding Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.alibaba.druid.sql.visitor.functions;
import static com.alibaba.druid.sql.visitor.SQLEvalVisitor.EVAL_VALUE;
import com.alibaba.druid.sql.ast.SQLExpr;
import com.alibaba.druid.sql.ast.expr.SQLMethodInvokeExpr;
import com.alibaba.druid.sql.visitor.SQLEvalVisitor;
public class BitLength implements Function {
public final static BitLength instance = new BitLength();
public Object eval(SQLEvalVisitor visitor, SQLMethodInvokeExpr x) {
if (x.getParameters().size() != 1) {
return SQLEvalVisitor.EVAL_ERROR;
}
SQLExpr param0 = x.getParameters().get(0);
param0.accept(visitor);
Object param0Value = param0.getAttributes().get(EVAL_VALUE);
if (param0Value == null) {
return SQLEvalVisitor.EVAL_ERROR;
}
if (param0Value instanceof String) {
return ((String) param0Value).getBytes().length * 8;
}
return SQLEvalVisitor.EVAL_ERROR;
}
}
@@ -0,0 +1,54 @@
/*
* Copyright 1999-2011 Alibaba Group Holding Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.alibaba.druid.sql.visitor.functions;
import static com.alibaba.druid.sql.visitor.SQLEvalVisitor.EVAL_VALUE;
import java.math.BigDecimal;
import com.alibaba.druid.sql.ast.SQLExpr;
import com.alibaba.druid.sql.ast.expr.SQLMethodInvokeExpr;
import com.alibaba.druid.sql.visitor.SQLEvalVisitor;
public class Char implements Function {
public final static Char instance = new Char();
public Object eval(SQLEvalVisitor visitor, SQLMethodInvokeExpr x) {
if (x.getParameters().size() == 0) {
return SQLEvalVisitor.EVAL_ERROR;
}
StringBuffer buf = new StringBuffer(x.getParameters().size());
for (SQLExpr param : x.getParameters()) {
param.accept(visitor);
Object paramValue = param.getAttributes().get(EVAL_VALUE);
if (paramValue instanceof Number) {
int charCode = ((Number) paramValue).intValue();
buf.append((char) charCode);
} else if (paramValue instanceof String) {
int charCode = new BigDecimal((String)paramValue).intValue();
buf.append((char) charCode);
} else {
return SQLEvalVisitor.EVAL_ERROR;
}
}
return buf.toString();
}
}
@@ -0,0 +1,53 @@
/*
* Copyright 1999-2011 Alibaba Group Holding Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.alibaba.druid.sql.visitor.functions;
import static com.alibaba.druid.sql.visitor.SQLEvalVisitor.EVAL_VALUE;
import com.alibaba.druid.sql.ast.SQLExpr;
import com.alibaba.druid.sql.ast.expr.SQLMethodInvokeExpr;
import com.alibaba.druid.sql.visitor.SQLEvalVisitor;
public class Elt implements Function {
public final static Elt instance = new Elt();
public Object eval(SQLEvalVisitor visitor, SQLMethodInvokeExpr x) {
if (x.getParameters().size() <= 1) {
return SQLEvalVisitor.EVAL_ERROR;
}
SQLExpr param0 = x.getParameters().get(0);
param0.accept(visitor);
Object param0Value = param0.getAttributes().get(EVAL_VALUE);
int param0IntValue;
if (!(param0Value instanceof Number)) {
return SQLEvalVisitor.EVAL_ERROR;
}
param0IntValue = ((Number) param0Value).intValue();
if (param0IntValue >= x.getParameters().size()) {
return null;
}
SQLExpr item = x.getParameters().get(param0IntValue);
item.accept(visitor);
Object itemValue = item.getAttributes().get(EVAL_VALUE);
return itemValue;
}
}
@@ -17,12 +17,11 @@ package com.alibaba.druid.sql.visitor.functions;
import static com.alibaba.druid.sql.visitor.SQLEvalVisitor.EVAL_VALUE;
import org.apache.xerces.impl.dv.util.HexBin;
import com.alibaba.druid.sql.ast.SQLExpr;
import com.alibaba.druid.sql.ast.expr.SQLMethodInvokeExpr;
import com.alibaba.druid.sql.parser.ParserException;
import com.alibaba.druid.sql.visitor.SQLEvalVisitor;
import com.alibaba.druid.util.HexBin;
public class Hex implements Function {
@@ -0,0 +1,83 @@
/*
* Copyright 1999-2011 Alibaba Group Holding Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.alibaba.druid.sql.visitor.functions;
import static com.alibaba.druid.sql.visitor.SQLEvalVisitor.EVAL_VALUE;
import com.alibaba.druid.sql.ast.SQLExpr;
import com.alibaba.druid.sql.ast.expr.SQLMethodInvokeExpr;
import com.alibaba.druid.sql.visitor.SQLEvalVisitor;
public class Insert implements Function {
public final static Insert instance = new Insert();
public Object eval(SQLEvalVisitor visitor, SQLMethodInvokeExpr x) {
if (x.getParameters().size() != 4) {
return SQLEvalVisitor.EVAL_ERROR;
}
SQLExpr param0 = x.getParameters().get(0);
SQLExpr param1 = x.getParameters().get(1);
SQLExpr param2 = x.getParameters().get(2);
SQLExpr param3 = x.getParameters().get(3);
param0.accept(visitor);
param1.accept(visitor);
param2.accept(visitor);
param3.accept(visitor);
Object param0Value = param0.getAttributes().get(EVAL_VALUE);
Object param1Value = param1.getAttributes().get(EVAL_VALUE);
Object param2Value = param2.getAttributes().get(EVAL_VALUE);
Object param3Value = param3.getAttributes().get(EVAL_VALUE);
if (!(param0Value instanceof String)) {
return SQLEvalVisitor.EVAL_ERROR;
}
if (!(param1Value instanceof Number)) {
return SQLEvalVisitor.EVAL_ERROR;
}
if (!(param2Value instanceof Number)) {
return SQLEvalVisitor.EVAL_ERROR;
}
if (!(param3Value instanceof String)) {
return SQLEvalVisitor.EVAL_ERROR;
}
String str = (String) param0Value;
int pos = ((Number) param1Value).intValue();
int len = ((Number) param2Value).intValue();
String newstr = (String) param3Value;
if (pos <= 0) {
return str;
}
if (pos == 1) {
if (len > str.length()) {
return newstr;
}
return newstr + str.substring(len);
}
String first = str.substring(0, pos - 1);
if (pos + len - 1 > str.length()) {
return first + newstr;
}
return first + newstr + str.substring(pos + len - 1);
}
}
@@ -0,0 +1,68 @@
/*
* Copyright 1999-2011 Alibaba Group Holding Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.alibaba.druid.sql.visitor.functions;
import static com.alibaba.druid.sql.visitor.SQLEvalVisitor.EVAL_VALUE;
import java.util.List;
import com.alibaba.druid.sql.ast.SQLExpr;
import com.alibaba.druid.sql.ast.expr.SQLMethodInvokeExpr;
import com.alibaba.druid.sql.visitor.SQLEvalVisitor;
public class Locate implements Function {
public final static Locate instance = new Locate();
public Object eval(SQLEvalVisitor visitor, SQLMethodInvokeExpr x) {
List<SQLExpr> params = x.getParameters();
int paramSize = params.size();
if (paramSize != 2 && paramSize != 3) {
return SQLEvalVisitor.EVAL_ERROR;
}
SQLExpr param0 = params.get(0);
SQLExpr param1 = params.get(1);
SQLExpr param2 = null;
param0.accept(visitor);
param1.accept(visitor);
if (paramSize == 3) {
param2 = params.get(2);
param2.accept(visitor);
}
Object param0Value = param0.getAttributes().get(EVAL_VALUE);
Object param1Value = param1.getAttributes().get(EVAL_VALUE);
if (param0Value == null || param1Value == null) {
return SQLEvalVisitor.EVAL_ERROR;
}
String strValue0 = param0Value.toString();
String strValue1 = param1Value.toString();
if (paramSize == 2) {
int result = strValue1.indexOf(strValue0) + 1;
return result;
}
Object param2Value = param2.getAttributes().get(EVAL_VALUE);
int start = ((Number) param2Value).intValue();
int result = strValue1.indexOf(strValue0, start + 1) + 1;
return result;
}
}
@@ -0,0 +1,67 @@
/*
* Copyright 1999-2011 Alibaba Group Holding Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.alibaba.druid.sql.visitor.functions;
import static com.alibaba.druid.sql.visitor.SQLEvalVisitor.EVAL_VALUE;
import java.util.List;
import com.alibaba.druid.sql.ast.SQLExpr;
import com.alibaba.druid.sql.ast.expr.SQLMethodInvokeExpr;
import com.alibaba.druid.sql.visitor.SQLEvalVisitor;
public class Lpad implements Function {
public final static Lpad instance = new Lpad();
public Object eval(SQLEvalVisitor visitor, SQLMethodInvokeExpr x) {
List<SQLExpr> params = x.getParameters();
int paramSize = params.size();
if (paramSize != 3) {
return SQLEvalVisitor.EVAL_ERROR;
}
SQLExpr param0 = params.get(0);
SQLExpr param1 = params.get(1);
SQLExpr param2 = params.get(2);
param0.accept(visitor);
param1.accept(visitor);
param2.accept(visitor);
Object param0Value = param0.getAttributes().get(EVAL_VALUE);
Object param1Value = param1.getAttributes().get(EVAL_VALUE);
Object param2Value = param2.getAttributes().get(EVAL_VALUE);
if (param0Value == null || param1Value == null || param2Value == null) {
return SQLEvalVisitor.EVAL_ERROR;
}
String strValue0 = param0Value.toString();
int len = ((Number) param1Value).intValue();
String strValue1 = param2Value.toString();
String result = strValue0;
if (result.length() > len) {
return result.substring(0, len);
}
while (result.length() < len) {
result = strValue1 + result;
}
return result;
}
}
@@ -0,0 +1,57 @@
/*
* Copyright 1999-2011 Alibaba Group Holding Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.alibaba.druid.sql.visitor.functions;
import static com.alibaba.druid.sql.visitor.SQLEvalVisitor.EVAL_VALUE;
import com.alibaba.druid.sql.ast.SQLExpr;
import com.alibaba.druid.sql.ast.expr.SQLMethodInvokeExpr;
import com.alibaba.druid.sql.visitor.SQLEvalVisitor;
public class Ltrim implements Function {
public final static Ltrim instance = new Ltrim();
public Object eval(SQLEvalVisitor visitor, SQLMethodInvokeExpr x) {
if (x.getParameters().size() != 1) {
return SQLEvalVisitor.EVAL_ERROR;
}
SQLExpr param0 = x.getParameters().get(0);
param0.accept(visitor);
Object param0Value = param0.getAttributes().get(EVAL_VALUE);
if (param0Value == null) {
return SQLEvalVisitor.EVAL_ERROR;
}
String strValue = param0Value.toString();
int index = -1;
for (int i = 0; i < strValue.length(); ++i) {
if (!Character.isWhitespace(strValue.charAt(i))) {
index = i;
break;
}
}
if (index <= 0) {
return strValue;
} else {
return strValue.substring(index);
}
}
}
@@ -0,0 +1,80 @@
/*
* Copyright 1999-2011 Alibaba Group Holding Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.alibaba.druid.sql.visitor.functions;
import static com.alibaba.druid.sql.visitor.SQLEvalVisitor.EVAL_VALUE;
import java.util.List;
import com.alibaba.druid.sql.ast.SQLExpr;
import com.alibaba.druid.sql.ast.expr.SQLMethodInvokeExpr;
import com.alibaba.druid.sql.visitor.SQLEvalVisitor;
public class Substring implements Function {
public final static Substring instance = new Substring();
public Object eval(SQLEvalVisitor visitor, SQLMethodInvokeExpr x) {
List<SQLExpr> params = x.getParameters();
int paramSize = params.size();
if (paramSize != 2 && paramSize != 3) {
return SQLEvalVisitor.EVAL_ERROR;
}
SQLExpr param0 = params.get(0);
SQLExpr param1 = params.get(1);
param0.accept(visitor);
param1.accept(visitor);
Object param0Value = param0.getAttributes().get(EVAL_VALUE);
Object param1Value = param1.getAttributes().get(EVAL_VALUE);
if (param0Value == null || param1Value == null) {
return SQLEvalVisitor.EVAL_ERROR;
}
String str = param0Value.toString();
int index = ((Number) param1Value).intValue();
if (paramSize == 2) {
if (index < 0) {
int lastIndex = str.length() + index ;
return str.substring(lastIndex);
}
return str.substring(index - 1);
}
SQLExpr param2 = params.get(2);
param2.accept(visitor);
Object param2Value = param2.getAttributes().get(EVAL_VALUE);
if (param2Value == null) {
return SQLEvalVisitor.EVAL_ERROR;
}
int len = ((Number) param2Value).intValue();
String result;
if (index < 0) {
int lastIndex = str.length() + index ;
result = str.substring(lastIndex);
} else {
result = str.substring(index - 1);
}
return result.substring(0, len);
}
}
@@ -15,17 +15,15 @@
*/
package com.alibaba.druid.sql.visitor.functions;
import static com.alibaba.druid.sql.visitor.SQLEvalVisitor.EVAL_VALUE;
import static com.alibaba.druid.sql.visitor.SQLEvalVisitor.EVAL_EXPR;
import static com.alibaba.druid.sql.visitor.SQLEvalVisitor.EVAL_VALUE;
import java.io.UnsupportedEncodingException;
import org.apache.xerces.impl.dv.util.HexBin;
import com.alibaba.druid.sql.ast.SQLExpr;
import com.alibaba.druid.sql.ast.expr.SQLMethodInvokeExpr;
import com.alibaba.druid.sql.parser.ParserException;
import com.alibaba.druid.sql.visitor.SQLEvalVisitor;
import com.alibaba.druid.util.HexBin;
public class Unhex implements Function {
@@ -33,7 +31,7 @@ public class Unhex implements Function {
public Object eval(SQLEvalVisitor visitor, SQLMethodInvokeExpr x) {
if (x.getParameters().size() != 1) {
throw new ParserException("argument's != 1, " + x.getParameters().size());
return SQLEvalVisitor.EVAL_ERROR;
}
SQLExpr param0 = x.getParameters().get(0);