001package gudusoft.gsqlparser.stmt;
002
003import gudusoft.gsqlparser.*;
004import gudusoft.gsqlparser.compiler.TFrame;
005import gudusoft.gsqlparser.nodes.TBlockSqlNode;
006import gudusoft.gsqlparser.nodes.TCompoundSqlNode;
007import gudusoft.gsqlparser.nodes.TParseTreeVisitor;
008
009/**
010 * sql block may have label name.
011 * <br> This class is just a wrapper of  {@link TBlockSqlNode}, so please use {@link  #getBlockBody()} to get further information.
012 * <br>
013 * Groups related declarations and statements, is the basic unit of a PL/SQL source program.
014 *
015 * @see gudusoft.gsqlparser.stmt.TCommonStoredProcedureSqlStatement#declareStatements
016 * @see gudusoft.gsqlparser.stmt.TCommonStoredProcedureSqlStatement#bodyStatements
017 */
018public class TCommonBlock extends TCommonStoredProcedureSqlStatement {
019    public TCommonBlock(EDbVendor dbvendor){
020        super(dbvendor);
021        sqlstatementtype = ESqlStatementType.sst_plsql_block;
022        }
023
024    public int doParseStatement(TCustomSqlStatement psql) {
025        switch (dbvendor){
026            case dbvdb2:
027                if (rootNode instanceof  TCompoundSqlNode){
028                    TCompoundSqlNode db2CompoundSqlNode = (TCompoundSqlNode) rootNode;
029                    this.blockBody = new TBlockSqlNode();
030                    this.blockBody.init(db2CompoundSqlNode.getStmts());
031                    this.blockBody.setDeclareStmts(db2CompoundSqlNode.getDeclareStmts());
032                    this.blockBody.setStartToken(db2CompoundSqlNode.getStartToken());
033                    this.blockBody.setEndToken(db2CompoundSqlNode.getEndToken());
034                }else {
035                    this.blockBody = (TBlockSqlNode)rootNode;
036                }
037                break;
038            default:
039                if (rootNode instanceof TBlockSqlNode) {
040                    this.blockBody = (TBlockSqlNode) rootNode;
041                    if (this.blockBody.getLabelName() == null) {
042                        this.blockBody.setLabelName(this.getLabelName());
043                    }
044                } else if (rootNode instanceof TCustomSqlStatement) {
045                    // Top-level scripting statement (WHILE, FOR, LOOP, IF) parsed as TCommonBlock
046                    // rootNode is TLoopStmt/TIfStmt etc. - delegate parsing to it directly
047                    TCustomSqlStatement scriptingStmt = (TCustomSqlStatement) rootNode;
048                    super.doParseStatement(psql);
049                    scriptingStmt.doParseStatement(this);
050                    return 0;
051                }
052                break;
053        }
054
055
056         super.doParseStatement(psql);
057         TFrame currentFrame = new TFrame(this.stmtScope);
058         TFrame upFrame = getFrameStack().peek();
059         if (upFrame.getScope().isRoutine()){
060             this.stmtScope.setEnclosingScope(upFrame.getScope());
061         }
062         currentFrame.pushMeToStack(getFrameStack());
063
064        if (this.blockBody != null) {
065            this.blockBody.doParse(this, ESqlClause.unknown);
066        }
067
068        currentFrame.popMeFromStack(getFrameStack());
069        return 0;
070
071
072    }
073
074
075    public void accept(TParseTreeVisitor v){
076        v.preVisit(this);
077        v.postVisit(this);
078    }
079
080    public void acceptChildren(TParseTreeVisitor v){
081        v.preVisit(this);
082        if(blockBody!=null) {
083            blockBody.acceptChildren(v);
084        }
085//        if (getDeclareStatements().size() > 0) getDeclareStatements().acceptChildren(v);
086//        if (getBodyStatements().size() > 0 ) getBodyStatements().acceptChildren(v);
087        v.postVisit(this);
088    }
089
090}