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