Java 用于获取WHERE子句的FoundationDB SQL解析器

Java 用于获取WHERE子句的FoundationDB SQL解析器,java,sql,eclipse,parsing,foundationdb,Java,Sql,Eclipse,Parsing,Foundationdb,我正在使用foundationDB SQL解析器()在Java内部解析查询,但我对解析器使用查询的访问者设计模式不太熟悉。 我想向解析器发送一个查询,如下所示:“从c中选择a,b,其中d>5”,并得到结果: 选择子句中的所有字段名称(已完成) 将表名输入到FROM子句中(已完成) 将列名称、操作数和表达式输入到WHERE子句中 这就是我正在实施的代码: @Override public QueryDescription parse() throws StandardException {

我正在使用foundationDB SQL解析器()在Java内部解析查询,但我对解析器使用查询的访问者设计模式不太熟悉。
我想向解析器发送一个查询,如下所示:“从c中选择a,b,其中d>5”,并得到结果:

  • 选择子句中的所有字段名称(已完成)
  • 将表名输入到FROM子句中(已完成)
  • 将列名称、操作数和表达式输入到WHERE子句中
  • 这就是我正在实施的代码:

        @Override
    public QueryDescription parse() throws StandardException {
    
        SQLParser parser = new SQLParser();
    
        StatementNode stmt = parser.parseStatement(sql);
    
        Visitor v = new Visitor() {
    
            @Override
            public boolean visitChildrenFirst(Visitable arg0) {
                // TODO Auto-generated method stub
                return false;
            }
    
            @Override
            public Visitable visit(Visitable arg0) throws StandardException {
    
                // Temporary stores the QueryDescription parameters
                StatementEnum se = null;
                String fromTable = null;
                String[] fields = null;
    
                if(arg0 instanceof CursorNode) {
                    CursorNode cn = (CursorNode) arg0;
    
                    // print out what statement is been declared in sql query
                    System.out.println("Statement: " + cn.statementToString());
    
                    // temporarly stores the statement
                    String statement = cn.statementToString();
    
                    // creates the right StatementEnum
                    if(statement == "CREATE TABLE") {
                        se = StatementEnum.CREATE_TABLE;
                    } else if(statement == "INSERT") {
                        se = StatementEnum.INSERT;
                    } else if(statement == "SELECT") {
                        se = StatementEnum.SELECT;
                    } else if(statement == "DROP TABLE") {
                        se = StatementEnum.DROP_TABLE;
                    }
                } 
    
                description = new QueryDescription(se, fromTable, fields);
    
                return arg0;
            }
    
            @Override
            public boolean stopTraversal() { return false; }
    
            @Override
            public boolean skipChildren(Visitable arg0) throws StandardException { return false; }
        };  
        stmt.accept(v);
    
        // TODO remove, only for debug purpose
        stmt.treePrint();
    
        return description;
    }
    
    这就是QueryDescription类代码:

    public class QueryDescription {
    
        /* Member variables: */
        private QueryTypeEnum queryType;
        private StatementEnum statement;
        private String fromTable;
        private String[] fields;
    
    
        /* Constructors: */
        /**
         * 
         * @param statement
         * @param fromTable
         * @param fields
         */
        public QueryDescription(StatementEnum statement, String fromTable, String[] fields) {
            this.statement = statement;
            this.fromTable = fromTable;
            this.fields = fields;
        }
    
    
        /* Methods: */
        /**
         * Analyze which type of query is the one passed by parameter and assigns the right queryTypeEnum
         */
        public void assignType() {
    
            switch(statement) {
    
                case CREATE_TABLE:
                    break;
    
                case SELECT:
                    if(fields[0] == "allFields")
                        queryType = QueryTypeEnum.DUMP;
                    else {
                        // TODO risolvere questione del WHERE
                        queryType = QueryTypeEnum.SELECT_FROM;
                    }
                    break;
    
                case UPDATE:
                    break;
    
                case INSERT:
                    break;
    
                case DROP_TABLE:
                    break;
            }
        }
    
    
        /* Getters and Setter: */
        /**
         * 
         * @return the queryType
         */
        public QueryTypeEnum getQueryType() {
            return queryType;
        }
    
        /**
         * 
         * @return the statement
         */
        public StatementEnum getStatement() {
            return statement;
        }
    
        /**
         * 
         * @return the from table
         */
        public String getFromTable() {
            return fromTable;
        }
    
        /**
         * 
         * @return the fields
         */
        public String[] getFields() {
            return fields;
        }
    }
    

    您的代码没有显示
    QueryDescription
    类的功能,但我可以猜测

    在处理where子句时,需要寻找三种类型的节点:

    • BinaryLogicalOperatorNode
      -这有AND,OR,IS运算符,用于分隔WHERE子句中的各个子句

    • BinaryOperatorNode
      -这有个人>,非常感谢您的快速回答,我想进一步了解如何检测where子句中的左右术语,就像treePrint()方法可以做的那样:查询:“从c中选择a,b,其中d>5”结果:leftOperator:com.foundationdb.sql.parser。ColumnReference@3f3aef95columnName:表名:null类型:null RightOperator:com.foundationdb.sql.parser。NumericConstantNode@36473fa1值:5类型:整数不为空
      Visitor v = new Visitor() {
          List<String> fromTable = new ArrayList<String>();
          List<String> fields = new ArrayList<String>();
      
          // other Visitor methods go here, not copied for conciseness. 
      
          @Override
          public Visitable visit(Visitable arg0) throws StandardException {
              // other code from your visit() method goes here
              // 
              if (arg0 instanceof FromBaseTable) {
                 FromBaseTable table = (FromBaseTable)arg0;
                 fromTable.append(table.getTableName());
              } else if (arg0 instanceof ColumnReference) {
                 ColumnReference column = (ColumnReference) arg0;
                 fields.append(column.getColumnName())
              }
              // Remove the call to create QueryDescription
          }
          public QueryDescription getQueryDescription() {
              return new QueryDescription(se, fromTable, fields)
          }
      }
      
      stmt.accept(v);
      QueryDescription description = v.getQueryDescription();