mirror of
https://github.com/alibaba/druid.git
synced 2023-03-04 19:17:16 +00:00
improve SQL Eval support
This commit is contained in:
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user