001package gudusoft.gsqlparser.stmt;
002
003import gudusoft.gsqlparser.*;
004import gudusoft.gsqlparser.nodes.*;
005
006/**
007 * Represents cursor related statement, including:
008 * <p>Cursor declaration
009 * <p>Cursor specification
010 * <p>Cursor body
011 * <p>Ref cursor type definition
012 */
013
014public class TCursorDeclStmt extends TCustomSqlStatement {
015
016    public enum CursorKind { declaration, specification, body, typeDefinition,resultsetName};
017    private CursorKind cursorKind = CursorKind.declaration;
018
019    public CursorKind getCursorKind() {
020        return cursorKind;
021    }
022
023    public final static int     kind_cursor_declaration = 1;
024    public final static int     kind_cursor_specification = 2;
025    public final static int     kind_cursor_body = 3;
026    public final static int     kind_ref_cursor_type_definition = 4;
027
028    private int kind = kind_cursor_declaration;
029
030    public void setKind(int kind) {
031        this.kind = kind;
032        switch (kind){
033            case kind_cursor_declaration:
034                this.cursorKind = CursorKind.declaration;
035                break;
036            case kind_cursor_specification:
037                this.cursorKind = CursorKind.specification;
038                break;
039            case kind_cursor_body:
040                this.cursorKind = CursorKind.body;
041                break;
042            case kind_ref_cursor_type_definition:
043                this.cursorKind =  CursorKind.typeDefinition;
044                break;
045        }
046
047    }
048
049    /**
050     * what's kind of SQL statement this class represents for.
051     *
052     * @deprecated since 2.5.0.9, please use {@link #getCursorKind()} instead.
053     */
054    public int getKind() {
055
056        return kind;
057    }
058
059    public TCursorDeclStmt(){
060        this(EDbVendor.dbvoracle);
061    }
062     public TCursorDeclStmt(EDbVendor dbvendor){
063        super(dbvendor);
064        sqlstatementtype = ESqlStatementType.sst_cursordecl;
065        }
066
067    void buildsql() {
068    }
069
070    void clear() {
071    }
072
073    /**
074     * A SQL SELECT statement. If the cursor declaration declares parameters, each parameter must appear in select_statement.
075     * @return
076     */
077    public TSelectSqlStatement getSubquery() {
078        return subquery;
079    }
080
081    String getasprettytext() {
082        return "";
083    }
084
085    void iterate(TVisitorAbs pvisitor) {
086    }
087
088    public int doParseStatement(TCustomSqlStatement psql) {
089        super.doParseStatement(psql);
090        
091        if (this.cursorName != null){
092            this.cursorName.setDbObjectType(EDbObjectType.cursor);
093        }
094
095         // push parameterDeclarations into symbolTable
096         if (this.getCursorParameterDeclarations() != null){
097             for(int i=0;i< this.getCursorParameterDeclarations().size();i++){
098                this.getTopStatement().getSymbolTable().push( new TSymbolTableItem(TObjectName.ttobjParameter,this, this.getCursorParameterDeclarations().getParameterDeclarationItem(i)));
099             }
100         }
101
102        if (subquery != null){
103            subquery.parsestatement(this,false);
104        }else if (selectSqlNode != null){
105            //postgresql
106            subquery = new TSelectSqlStatement(this.dbvendor);
107            subquery.rootNode = selectSqlNode;
108            subquery.doParseStatement(this);
109        }
110
111         // pop parameterDeclarations from symbolTable
112         if (this.getCursorParameterDeclarations() != null){
113             for(int i=0;i< this.getCursorParameterDeclarations().size();i++){
114                this.getTopStatement().getSymbolTable().pop();
115             }
116         }
117
118        return 0;
119    }
120
121    private TSelectSqlStatement subquery = null;
122    private TSelectSqlNode selectSqlNode = null;
123
124    private TObjectName resultsetName = null;//snowflake
125
126    public TObjectName getResultsetName() {
127        return resultsetName;
128    }
129
130    public void init(Object arg1)
131    {
132        if (arg1 instanceof TSelectSqlStatement){
133            subquery = (TSelectSqlStatement)arg1;
134        }else if (arg1 instanceof TSelectSqlNode){
135            selectSqlNode = (TSelectSqlNode)arg1;
136        }else if (arg1 instanceof TObjectName){
137            resultsetName = (TObjectName)arg1;
138        }
139    }
140
141    public void init(Object arg1,Object arg2){
142        this.cursorKind = (CursorKind)arg1;
143        switch (cursorKind){
144            case declaration:
145                if (arg1 instanceof TSelectSqlStatement){
146                    subquery = (TSelectSqlStatement)arg1;
147                }else if (arg1 instanceof TSelectSqlNode){
148                    selectSqlNode = (TSelectSqlNode)arg1;
149                }
150                break;
151            case resultsetName:
152                resultsetName = (TObjectName)arg2;
153                break;
154            default:
155                if (arg1 instanceof TSelectSqlStatement){
156                    subquery = (TSelectSqlStatement)arg1;
157                }else if (arg1 instanceof TSelectSqlNode){
158                    selectSqlNode = (TSelectSqlNode)arg1;
159                }
160                break;
161        }
162    }
163
164    private TObjectName cursorName;
165
166    public void setCursorName(TObjectName cursorName) {
167        this.cursorName = cursorName;
168    }
169
170    /**
171     * Name of an explicit cursor.
172     * @return
173     */
174    public TObjectName getCursorName() {
175
176        return cursorName;
177    }
178
179    private TParameterDeclarationList cursorParameterDeclarations = null;
180
181    /**
182     * List of cursor parameter declaration, which is represented by {@link gudusoft.gsqlparser.nodes.TParameterDeclaration}.
183     * @return
184     */
185    public TParameterDeclarationList getCursorParameterDeclarations() {
186        return cursorParameterDeclarations;
187    }
188
189    public void setCursorParameterDeclarations(TParameterDeclarationList cursorParameterDeclarations) {
190        this.cursorParameterDeclarations = cursorParameterDeclarations;
191    }
192
193    private TTypeName rowtype;
194
195    public void setRowtype(TTypeName rowtype) {
196        this.rowtype = rowtype;
197    }
198
199    /**
200     * A record type that represents a row in a database table or a row fetched from a previously declared cursor or cursor variable.
201     * @return
202     */
203    public TTypeName getRowtype() {
204
205        return rowtype;
206    }
207
208    private TObjectName cursorTypeName;
209
210    public void setCursorTypeName(TObjectName cursorTypeName) {
211        this.cursorTypeName = cursorTypeName;
212    }
213
214    /**
215     * Name of a REF CURSOR type. Valid only when kind = kind_ref_cursor_type_definition
216     * To create a cursor variable, define a REF CURSOR type, and then declare the cursor
217     * variable to be of that type. Declaring a cursor variable creates a pointer, not an item.
218     * @return
219     */
220    public TObjectName getCursorTypeName() {
221
222        return cursorTypeName;
223    }
224
225    public void accept(TParseTreeVisitor v){
226        v.preVisit(this);
227        v.postVisit(this);
228    }
229
230    public void acceptChildren(TParseTreeVisitor v){
231        v.preVisit(this);
232        if (getCursorParameterDeclarations() != null) getCursorParameterDeclarations().acceptChildren(v);
233        if (subquery != null) subquery.acceptChildren(v);
234        v.postVisit(this);
235    }
236
237    public void setSubquery(TSelectSqlStatement subquery) {
238        this.subquery = subquery;
239    }
240}