001package gudusoft.gsqlparser.nodes;
002
003import gudusoft.gsqlparser.*;
004import gudusoft.gsqlparser.stmt.TCreateProcedureStmt;
005
006/**
007* TBlockSqlNode represents a block in a stored procedure.
008 * It's used in {@link gudusoft.gsqlparser.stmt.TCreateFunctionStmt} and {@link gudusoft.gsqlparser.stmt.TCreateProcedureStmt}
009 * to retrieve the declarations and statements as shown below.
010 *<br><br>
011 * The mainly used methods are {@link #getDeclareStmts()} to retrieve the declarations, {@link #getBodyStatements()} to
012 * retrieve the statements.
013 * <br><br>
014 * {@link #getExceptionClause()} represents the exception section in the block if any.
015 *
016* <pre>{@code
017* [ <<label>> ]
018* [ DECLARE
019*     declarations ]
020* BEGIN
021*     statements
022* END [ label ];
023* }</pre>
024 *
025* @see gudusoft.gsqlparser.stmt.TCreateProcedureStmt
026 * @see gudusoft.gsqlparser.stmt.TCreateFunctionStmt
027*/
028public class TBlockSqlNode extends TNodeWithLabel {
029
030    protected TObjectName outerLabelName = null;
031    protected TStatementList declareStatements = null;
032    protected TStatementList bodyStatements = null;
033    protected TExceptionClause exceptionClause = null;
034
035    private TStatementListSqlNode stmts = null;
036    private TStatementListSqlNode declareStmts = null;
037
038    private boolean isParsed = false;
039
040    public void setParsed(boolean parsed) {
041        isParsed = parsed;
042    }
043
044    public boolean isParsed() {
045        return isParsed;
046    }
047
048    public void init(Object arg1)
049    {
050        stmts = (TStatementListSqlNode)arg1;
051    }
052
053
054
055    public TExceptionClause getExceptionClause() {
056        return exceptionClause;
057    }
058
059    public void setExceptionClause(TExceptionClause exceptionClause) {
060
061        this.exceptionClause = exceptionClause;
062    }
063
064
065    public TStatementListSqlNode getDeclareStmts() {
066        return declareStmts;
067    }
068
069    public TStatementListSqlNode getStmts() {
070        return stmts;
071    }
072
073
074    public void setStmts(TStatementListSqlNode stmts) {
075        this.stmts = stmts;
076    }
077
078    public void setDeclareStmts(TStatementListSqlNode declareStmts) {
079        this.declareStmts = declareStmts;
080    }
081
082
083    public void setOuterLabelName(TObjectName outerLabelName) {
084        this.outerLabelName = outerLabelName;
085    }
086    public TObjectName getOuterLabelName() {
087        return outerLabelName;
088    }
089
090
091
092    public void setDeclareStatements(TStatementList declareStatements) {
093        this.declareStatements = declareStatements;
094    }
095    public TStatementList getDeclareStatements() {
096        if (declareStatements == null){
097            declareStatements = new TStatementList();
098        }
099        return declareStatements;
100    }
101
102
103    public void setBodyStatements(TStatementList bodyStatements) {
104        this.bodyStatements = bodyStatements;
105    }
106    public TStatementList getBodyStatements() {
107        if (bodyStatements == null){
108            bodyStatements = new TStatementList();
109        }
110        return bodyStatements;
111    }
112
113
114    @Override
115    public void doParse(TCustomSqlStatement psql, ESqlClause plocation) {
116        if (isParsed) return;
117        super.doParse(psql, plocation);
118        if (declareStmts != null){
119            declareStmts.doParse(psql,plocation);
120            for(int i=0;i<declareStmts.size();i++){
121                if (declareStmts.getStatementSqlNode(i).getStmt() != null) {
122                    declareStmts.getStatementSqlNode(i).getStmt().setParent(this);
123                    this.getDeclareStatements().add(declareStmts.getStatementSqlNode(i).getStmt());
124                }
125            }
126
127            for(int i=0;i<declareStmts.size();i++) {
128                if (declareStmts.getStatementSqlNode(i).getStmt() != null) {
129                    psql.getTopStatement().getSymbolTable().push(new TSymbolTableItem(TObjectName.ttobjVariable
130                            , psql
131                            ,declareStmts.getStatementSqlNode(i).getStmt())
132                    );
133                }
134            }
135        }
136
137        if (stmts != null){
138            stmts.doParse(psql,plocation);
139
140            // Teradata: validate that statements in compound blocks are terminated with semicolons
141            if (psql.dbvendor == EDbVendor.dbvteradata) {
142                TCreateProcedureStmt.validateSemicolonsBetweenStatements(psql, stmts);
143            }
144
145            for(int i=0;i<stmts.size();i++){
146                if (stmts.getStatementSqlNode(i).getStmt() != null) {
147                    stmts.getStatementSqlNode(i).getStmt().setParent(this);
148                    this.getBodyStatements().add(stmts.getStatementSqlNode(i).getStmt());
149                }
150            }
151        }
152
153        if (exceptionClause != null){
154            exceptionClause.doParse(psql,plocation);
155            exceptionClause.setParent(this);
156            this.setExceptionClause(exceptionClause);
157        }
158
159        if (declareStmts != null){
160
161            // pop variable declare from symbolTable
162            for(int i=0;i<declareStmts.size();i++){
163                psql.getTopStatement().getSymbolTable().pop();
164            }
165
166        }
167    }
168
169    public void accept(TParseTreeVisitor v){
170        v.preVisit(this);
171        v.postVisit(this);
172    }
173
174    public void acceptChildren(TParseTreeVisitor v){
175        v.preVisit(this);
176        if ((this.getDeclareStatements() != null)&&(this.getDeclareStatements().size()>0)) this.getDeclareStatements().acceptChildren(v);
177        if ((this.getBodyStatements() != null)&&(this.getBodyStatements().size()>0)) this.getBodyStatements().acceptChildren(v);
178        if (exceptionClause != null) exceptionClause.acceptChildren(v);
179        v.postVisit(this);
180    }
181
182}