From 0d76d92c8164a17d59d35749999e444505792bf7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=B8=A9=E5=B0=91?= Date: Sat, 19 May 2012 11:50:41 +0800 Subject: [PATCH] hbse sql support --- .../druid/hbase/HBasePreparedStatement.java | 22 +++++++- .../alibaba/druid/hbase/exec/ExecutePlan.java | 2 +- .../druid/hbase/exec/ExecutePlanAdapter.java | 2 +- .../druid/hbase/exec/InsertExecutePlan.java | 55 ++++++++++++++++++- .../hbase/exec/SingleTableExecutePlan.java | 3 +- .../mysql/visitor/MySqlEvalVisitorImpl.java | 17 +++++- .../druid/sql/visitor/SQLEvalVisitor.java | 4 ++ .../druid/sql/visitor/SQLEvalVisitorImpl.java | 15 ++++- .../sql/visitor/SQLEvalVisitorUtils.java | 20 ++++--- 9 files changed, 119 insertions(+), 21 deletions(-) diff --git a/src/main/java/com/alibaba/druid/hbase/HBasePreparedStatement.java b/src/main/java/com/alibaba/druid/hbase/HBasePreparedStatement.java index fd76afbb30..713cb98cc3 100644 --- a/src/main/java/com/alibaba/druid/hbase/HBasePreparedStatement.java +++ b/src/main/java/com/alibaba/druid/hbase/HBasePreparedStatement.java @@ -7,14 +7,18 @@ import java.util.List; import com.alibaba.druid.common.jdbc.PreparedStatementBase; import com.alibaba.druid.hbase.exec.ExecutePlan; +import com.alibaba.druid.hbase.exec.InsertExecutePlan; import com.alibaba.druid.hbase.exec.SingleTableQueryExecutePlan; import com.alibaba.druid.sql.SQLUtils; +import com.alibaba.druid.sql.ast.SQLExpr; import com.alibaba.druid.sql.ast.SQLStatement; import com.alibaba.druid.sql.ast.expr.SQLIdentifierExpr; import com.alibaba.druid.sql.ast.statement.SQLExprTableSource; import com.alibaba.druid.sql.ast.statement.SQLInsertStatement; import com.alibaba.druid.sql.ast.statement.SQLSelectQueryBlock; import com.alibaba.druid.sql.ast.statement.SQLSelectStatement; +import com.alibaba.druid.sql.visitor.SQLEvalVisitor; +import com.alibaba.druid.sql.visitor.SQLEvalVisitorUtils; public class HBasePreparedStatement extends PreparedStatementBase implements PreparedStatement, HBaseStatementInterface { @@ -56,10 +60,24 @@ public class HBasePreparedStatement extends PreparedStatementBase implements Pre this.executePlan = singleTableQueryExecuetePlan; } else if (sqlStmt instanceof SQLInsertStatement) { SQLInsertStatement insertStmt = (SQLInsertStatement) sqlStmt; + + SQLEvalVisitor evalVisitor = SQLEvalVisitorUtils.createEvalVisitor(dbType); + insertStmt.accept(evalVisitor); String tableName = ((SQLIdentifierExpr) insertStmt.getTableSource().getExpr()).getName(); - throw new SQLException("TODO"); + InsertExecutePlan insertExecutePlan = new InsertExecutePlan(); + insertExecutePlan.setTableName(tableName); + + for (int i = 0; i < insertStmt.getColumns().size(); ++i) { + SQLExpr columnExpr = insertStmt.getColumns().get(i); + SQLExpr valueExpr = insertStmt.getValues().getValues().get(i); + + String columnName = ((SQLIdentifierExpr) columnExpr).getName(); + insertExecutePlan.getColumns().put(columnName, valueExpr); + } + + this.executePlan = insertExecutePlan; } else { throw new SQLException("TODO"); } @@ -99,7 +117,7 @@ public class HBasePreparedStatement extends PreparedStatementBase implements Pre @Override public boolean execute() throws SQLException { - checkOpen(); + this.executePlan.execute(this); return false; } diff --git a/src/main/java/com/alibaba/druid/hbase/exec/ExecutePlan.java b/src/main/java/com/alibaba/druid/hbase/exec/ExecutePlan.java index 76dd8fb6f6..1dd36590cb 100644 --- a/src/main/java/com/alibaba/druid/hbase/exec/ExecutePlan.java +++ b/src/main/java/com/alibaba/druid/hbase/exec/ExecutePlan.java @@ -9,5 +9,5 @@ public interface ExecutePlan { HBaseResultSet executeQuery(HBasePreparedStatement statement) throws SQLException; - void execute(HBasePreparedStatement statement) throws SQLException; + boolean execute(HBasePreparedStatement statement) throws SQLException; } diff --git a/src/main/java/com/alibaba/druid/hbase/exec/ExecutePlanAdapter.java b/src/main/java/com/alibaba/druid/hbase/exec/ExecutePlanAdapter.java index e556128268..8e9ac73dde 100644 --- a/src/main/java/com/alibaba/druid/hbase/exec/ExecutePlanAdapter.java +++ b/src/main/java/com/alibaba/druid/hbase/exec/ExecutePlanAdapter.java @@ -13,7 +13,7 @@ public class ExecutePlanAdapter implements ExecutePlan { } @Override - public void execute(HBasePreparedStatement statement) throws SQLException { + public boolean execute(HBasePreparedStatement statement) throws SQLException { throw new UnsupportedOperationException(); } diff --git a/src/main/java/com/alibaba/druid/hbase/exec/InsertExecutePlan.java b/src/main/java/com/alibaba/druid/hbase/exec/InsertExecutePlan.java index 0665e252db..a6e2f35996 100644 --- a/src/main/java/com/alibaba/druid/hbase/exec/InsertExecutePlan.java +++ b/src/main/java/com/alibaba/druid/hbase/exec/InsertExecutePlan.java @@ -1,21 +1,64 @@ package com.alibaba.druid.hbase.exec; import java.sql.SQLException; +import java.util.LinkedHashMap; +import java.util.Map; import org.apache.hadoop.hbase.client.HTableInterface; +import org.apache.hadoop.hbase.client.Put; +import org.apache.hadoop.hbase.util.Bytes; import com.alibaba.druid.hbase.HBaseConnection; import com.alibaba.druid.hbase.HBasePreparedStatement; +import com.alibaba.druid.sql.ast.SQLExpr; +import com.alibaba.druid.sql.visitor.SQLEvalVisitorUtils; public class InsertExecutePlan extends SingleTableExecutePlan { + private Map columns = new LinkedHashMap(); + private byte[] family = Bytes.toBytes("d"); + @Override - public void execute(HBasePreparedStatement statement) throws SQLException { + public boolean execute(HBasePreparedStatement statement) throws SQLException { try { HBaseConnection connection = statement.getConnection(); HTableInterface htable = connection.getHTable(getTableName()); + String dbType = connection.getConnectProperties().getProperty("dbType"); - throw new UnsupportedOperationException(); + Put put = null; + for (Map.Entry entry : columns.entrySet()) { + String column = entry.getKey(); + SQLExpr valueExpr = entry.getValue(); + + Object value = SQLEvalVisitorUtils.eval(dbType, valueExpr, statement.getParameters()); + + if (value == null) { + continue; + } + + byte[] bytes; + + if (value instanceof String) { + String strValue = (String) value; + bytes = Bytes.toBytes(strValue); + } else if (value instanceof Integer) { + int intValue = ((Integer) value).intValue(); + bytes = Bytes.toBytes(intValue); + } else { + throw new SQLException("TODO"); // TODO + } + + if (put == null) { // first value is key, TODO + put = new Put(bytes); + } else { + byte[] qualifier = Bytes.toBytes(column); + put.add(family, qualifier, bytes); + } + } + + htable.put(put); + + return false; } catch (SQLException e) { throw e; } catch (Exception e) { @@ -23,4 +66,12 @@ public class InsertExecutePlan extends SingleTableExecutePlan { } } + public Map getColumns() { + return columns; + } + + public void setColumns(Map columns) { + this.columns = columns; + } + } diff --git a/src/main/java/com/alibaba/druid/hbase/exec/SingleTableExecutePlan.java b/src/main/java/com/alibaba/druid/hbase/exec/SingleTableExecutePlan.java index d0d63d85d6..e49ab07064 100644 --- a/src/main/java/com/alibaba/druid/hbase/exec/SingleTableExecutePlan.java +++ b/src/main/java/com/alibaba/druid/hbase/exec/SingleTableExecutePlan.java @@ -1,7 +1,7 @@ package com.alibaba.druid.hbase.exec; - public class SingleTableExecutePlan extends ExecutePlanAdapter { + private String tableName; public String getTableName() { @@ -11,4 +11,5 @@ public class SingleTableExecutePlan extends ExecutePlanAdapter { public void setTableName(String tableName) { this.tableName = tableName; } + } diff --git a/src/main/java/com/alibaba/druid/sql/dialect/mysql/visitor/MySqlEvalVisitorImpl.java b/src/main/java/com/alibaba/druid/sql/dialect/mysql/visitor/MySqlEvalVisitorImpl.java index bbb98b1ddd..2c25094427 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/mysql/visitor/MySqlEvalVisitorImpl.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/mysql/visitor/MySqlEvalVisitorImpl.java @@ -11,9 +11,11 @@ import com.alibaba.druid.sql.visitor.SQLEvalVisitorUtils; public class MySqlEvalVisitorImpl extends MySqlASTVisitorAdapter implements SQLEvalVisitor { - private List parameters = new ArrayList(); + private List parameters = new ArrayList(); - private int variantIndex = -1; + private int variantIndex = -1; + + private boolean markVariantIndex = true; public MySqlEvalVisitorImpl(){ this(new ArrayList(1)); @@ -46,8 +48,17 @@ public class MySqlEvalVisitorImpl extends MySqlASTVisitorAdapter implements SQLE public boolean visit(SQLVariantRefExpr x) { return SQLEvalVisitorUtils.visit(this, x); } - + public boolean visit(SQLBinaryOpExpr x) { return SQLEvalVisitorUtils.visit(this, x); } + + public boolean isMarkVariantIndex() { + return markVariantIndex; + } + + public void setMarkVariantIndex(boolean markVariantIndex) { + this.markVariantIndex = markVariantIndex; + } + } diff --git a/src/main/java/com/alibaba/druid/sql/visitor/SQLEvalVisitor.java b/src/main/java/com/alibaba/druid/sql/visitor/SQLEvalVisitor.java index a53412a214..7df2ca0c0f 100644 --- a/src/main/java/com/alibaba/druid/sql/visitor/SQLEvalVisitor.java +++ b/src/main/java/com/alibaba/druid/sql/visitor/SQLEvalVisitor.java @@ -13,4 +13,8 @@ public interface SQLEvalVisitor extends SQLASTVisitor { void setParameters(List parameters); int incrementAndGetVariantIndex(); + + boolean isMarkVariantIndex(); + + void setMarkVariantIndex(boolean markVariantIndex); } diff --git a/src/main/java/com/alibaba/druid/sql/visitor/SQLEvalVisitorImpl.java b/src/main/java/com/alibaba/druid/sql/visitor/SQLEvalVisitorImpl.java index 7d79df348f..84c1f31691 100644 --- a/src/main/java/com/alibaba/druid/sql/visitor/SQLEvalVisitorImpl.java +++ b/src/main/java/com/alibaba/druid/sql/visitor/SQLEvalVisitorImpl.java @@ -9,9 +9,11 @@ import com.alibaba.druid.sql.ast.expr.SQLVariantRefExpr; public class SQLEvalVisitorImpl extends SQLASTVisitorAdapter implements SQLEvalVisitor { - private List parameters = new ArrayList(); + private List parameters = new ArrayList(); - private int variantIndex = -1; + private int variantIndex = -1; + + private boolean markVariantIndex = true; public SQLEvalVisitorImpl(){ this(new ArrayList(1)); @@ -48,4 +50,13 @@ public class SQLEvalVisitorImpl extends SQLASTVisitorAdapter implements SQLEvalV public boolean visit(SQLBinaryOpExpr x) { return SQLEvalVisitorUtils.visit(this, x); } + + public boolean isMarkVariantIndex() { + return markVariantIndex; + } + + public void setMarkVariantIndex(boolean markVariantIndex) { + this.markVariantIndex = markVariantIndex; + } + } diff --git a/src/main/java/com/alibaba/druid/sql/visitor/SQLEvalVisitorUtils.java b/src/main/java/com/alibaba/druid/sql/visitor/SQLEvalVisitorUtils.java index 51773120cf..767d02d308 100644 --- a/src/main/java/com/alibaba/druid/sql/visitor/SQLEvalVisitorUtils.java +++ b/src/main/java/com/alibaba/druid/sql/visitor/SQLEvalVisitorUtils.java @@ -67,24 +67,24 @@ public class SQLEvalVisitorUtils { x.putAttribute(EVAL_VALUE, x.getText()); return true; } - + public static boolean visit(SQLEvalVisitor visitor, SQLBinaryOpExpr x) { x.getLeft().accept(visitor); x.getRight().accept(visitor); - + if (!x.getLeft().getAttributes().containsKey(EVAL_VALUE)) { return false; } - + if (!x.getRight().getAttributes().containsKey(EVAL_VALUE)) { return false; } - + if (SQLBinaryOperator.Add.equals(x.getOperator())) { Object value = _add(x.getLeft().getAttribute(EVAL_VALUE), x.getRight().getAttributes().get(EVAL_VALUE)); x.putAttribute(EVAL_VALUE, value); } - + return false; } @@ -96,10 +96,12 @@ public class SQLEvalVisitorUtils { x.putAttribute(EVAL_VAR_INDEX, varIndex); } - boolean containsValue = attributes.containsKey(EVAL_VALUE); - if (!containsValue) { - Object value = visitor.getParameters().get(varIndex.intValue()); - attributes.put(EVAL_VALUE, value); + if (visitor.getParameters().size() > 0) { + boolean containsValue = attributes.containsKey(EVAL_VALUE); + if (!containsValue) { + Object value = visitor.getParameters().get(varIndex.intValue()); + attributes.put(EVAL_VALUE, value); + } } return false;