001package gudusoft.gsqlparser.stmt;
002
003import gudusoft.gsqlparser.*;
004import gudusoft.gsqlparser.compiler.TSymbolTableManager;
005import gudusoft.gsqlparser.compiler.TVariable;
006import gudusoft.gsqlparser.nodes.TExpression;
007import gudusoft.gsqlparser.nodes.TObjectName;
008import gudusoft.gsqlparser.nodes.TParseTreeVisitor;
009import gudusoft.gsqlparser.nodes.TSelectSqlNode;
010import gudusoft.gsqlparser.nodes.TTypeName;
011
012/**
013 * The assignment statement sets the current value of a variable, field, parameter,
014 * or element that has been declared in the current scope.
015 */
016
017public class TAssignStmt extends TCustomSqlStatement {
018
019    public enum AssignType  {normal, variableAssignment, cursorAssignment,resultsetAssignment};
020
021    private AssignType assignType = AssignType.normal;
022
023    private TSelectSqlNode queryNode;
024    private TSelectSqlStatement query;
025
026    public TSelectSqlStatement getQuery() {
027        return query;
028    }
029
030    public AssignType getAssignType() {
031        return assignType;
032    }
033
034    private TObjectName resultsetName;
035
036    public TObjectName getResultsetName() {
037        return resultsetName;
038    }
039
040    private TObjectName variableName;
041
042    public TObjectName getVariableName() {
043        return variableName;
044    }
045
046    /**
047     * The data type of the variable in a LET statement (Snowflake).
048     * For example, in "let x INTEGER := 10;", this returns the INTEGER type.
049     */
050    private TTypeName dataType;
051
052    public TTypeName getDataType() {
053        return dataType;
054    }
055
056    public void setDataType(TTypeName dataType) {
057        this.dataType = dataType;
058    }
059
060    public TAssignStmt(){
061       this(EDbVendor.dbvoracle);
062    }
063
064    public TAssignStmt(TExpression pLeft, TExpression pExpr){
065        this(EDbVendor.dbvoracle);
066        this.left = pLeft;
067        this.expression = pExpr;
068    }
069
070
071     public TAssignStmt(EDbVendor dbvendor){
072        super(dbvendor);
073        sqlstatementtype = ESqlStatementType.sst_assignstmt;
074    }
075
076    void buildsql() {
077    }
078
079    void clear() {
080    }
081
082    String getasprettytext() {
083        return "";
084    }
085
086    void iterate(TVisitorAbs pvisitor) {
087    }
088
089
090
091    private TExpression left = null;
092
093    /**
094     * @return The expression whose value is to be assigned to the target (the item to the left of the
095     * assignment operator) when the assignment statement executes.
096     */
097    public TExpression getExpression() {
098        return expression;
099    }
100
101    /**
102     * Lefe side of this assignment, can be
103     * <ul>
104     * <li>attribute_name</li>
105     * <li>collection_name</li>
106     * <li>cursor_variable_name</li>
107     * <li>field_name</li>
108     * <li>host_cursor_variable_name</li>
109     * <li>host_variable_name</li>
110     * <li>object_name</li>
111     * <li>parameter_name</li>
112     * <li>record_name</li>
113     * <li>variable_name</li>
114     * </ul>
115     * @return  A TExpression object.
116     */
117    public TExpression getLeft() {
118        return left;
119    }
120
121    private TExpression expression = null;
122
123    public void setLeft(TExpression left) {
124        this.left = left;
125    }
126
127    public void setExpression(TExpression expression) {
128        this.expression = expression;
129    }
130
131    public void init(Object arg1,Object arg2)
132    {
133        if (arg1 instanceof TObjectName){
134            variableName = (TObjectName)arg1;
135        }else if (arg1 instanceof  TExpression){
136            left = (TExpression)arg1;
137        }
138
139        expression = (TExpression)arg2;
140    }
141
142    public void init(Object arg1, Object arg2,Object arg3){
143        this.assignType = (AssignType) arg1;
144        switch (this.assignType){
145            case variableAssignment:
146                this.variableName = (TObjectName) arg2;
147                this.expression = (TExpression) arg3;
148                break;
149            case cursorAssignment:
150                this.variableName = (TObjectName) arg2;
151                this.queryNode = (TSelectSqlNode)arg3;
152                break;
153            case resultsetAssignment:
154                this.variableName = (TObjectName) arg2;
155                this.resultsetName = (TObjectName) arg3;
156                break;
157        }
158
159    }
160
161    /**
162     * Init method for LET statement with datatype (Snowflake).
163     * @param arg1 AssignType
164     * @param arg2 variable name (TObjectName)
165     * @param arg3 datatype (TTypeName), can be null
166     * @param arg4 expression (TExpression)
167     */
168    public void init(Object arg1, Object arg2, Object arg3, Object arg4){
169        this.assignType = (AssignType) arg1;
170        if (this.assignType == AssignType.variableAssignment){
171            this.variableName = (TObjectName) arg2;
172            if (arg3 instanceof TTypeName){
173                this.dataType = (TTypeName) arg3;
174            }
175            this.expression = (TExpression) arg4;
176        }
177    }
178
179    public int doParseStatement(TCustomSqlStatement psql) {
180        super.doParseStatement(psql);
181
182        switch (getAssignType()){
183            case normal:
184                if (left != null){
185                    left.doParse(this,ESqlClause.spAssignValue);
186                    if (left.getExpressionType() == EExpressionType.simple_object_name_t){
187                        TVariable symbolVariable =  TSymbolTableManager.searchSymbolVariable(this.getFrameStack(), left.getObjectOperand().toString());
188                        if (symbolVariable != null){
189                            expression.evaluate(this.getFrameStack(),this);
190                            symbolVariable.setVariableStr(this.expression.getPlainText());
191                            if (expression.getStartToken() != null){
192                                symbolVariable.setLineNo(expression.getStartToken().lineNo);
193                                symbolVariable.setColumnNo(expression.getStartToken().columnNo);
194                            }
195                        }
196                    }
197                }
198
199                expression.doParse(this,ESqlClause.spAssignValue);
200                break;
201            case variableAssignment:
202                expression.doParse(this,ESqlClause.spAssignValue);
203                break;
204            case cursorAssignment:
205                query = new TSelectSqlStatement(this.dbvendor);
206                query.rootNode = queryNode;
207                query.doParseStatement(this);
208                break;
209        }
210
211        return 0;
212    }
213
214    public void accept(TParseTreeVisitor v){
215        v.preVisit(this);
216        v.postVisit(this);
217    }
218
219    public void acceptChildren(TParseTreeVisitor v){
220        v.preVisit(this);
221        if (left != null){
222            left.acceptChildren(v);
223        }
224        if (expression != null){
225            expression.acceptChildren(v);
226        }else{
227            TBaseType.log("Value expression in assign statement is not specified",TLog.WARNING);
228        }
229
230        v.postVisit(this);
231    }
232}