001package gudusoft.gsqlparser.nodes;
002
003import gudusoft.gsqlparser.*;
004import gudusoft.gsqlparser.compiler.*;
005import gudusoft.gsqlparser.nodes.couchbase.*;
006import gudusoft.gsqlparser.nodes.hive.THiveVariable;
007import gudusoft.gsqlparser.nodes.teradata.TDataConversion;
008import gudusoft.gsqlparser.stmt.TSelectSqlStatement;
009import gudusoft.gsqlparser.sqlenv.ESQLDataObjectType;
010import gudusoft.gsqlparser.util.SQLUtil;
011
012import java.util.ArrayDeque;
013import java.util.ArrayList;
014import java.util.Deque;
015import java.util.Stack;
016
017
018class calculateExprVisitor implements IExpressionVisitor {
019
020    TCustomSqlStatement sqlStatement;
021
022    Stack<TFrame> frameStack;
023
024    public calculateExprVisitor(Stack<TFrame> pframeStack, TCustomSqlStatement pSqlStatement){
025        sqlStatement = pSqlStatement;
026        this.frameStack = pframeStack;
027    }
028
029    Stack<TExpression> expressionStack = new Stack<>();
030
031    void evaluateLeafExpr(TExpression expr){
032        String plainText = expr.getPlainText();
033
034        switch (expr.getExpressionType()){
035            case simple_constant_t:
036                TConstant constant = expr.getConstantOperand();
037                switch (constant.getLiteralType()){
038                    case etString:
039                        plainText = TBaseType.getStringInsideLiteral(plainText);
040                        expr.setVal(plainText);
041                        expr.setDataType(TPrimitiveType.String);
042                        if (constant.getStartToken() != null){
043                           expr.setPlainTextLineNo(constant.getStartToken().lineNo);
044                           expr.setPlainTextColumnNo(constant.getStartToken().columnNo);
045                        }
046
047                        break;
048                    case etNumber:
049                        break;
050                }
051                break;
052            case function_t:
053                plainText = expr.getFunctionCall().getFunctionName().toString();
054                expr.setPlainTextLineNo(expr.getFunctionCall().getFunctionName().getStartToken().lineNo);
055                expr.setPlainTextColumnNo(expr.getFunctionCall().getFunctionName().getStartToken().columnNo);
056                break;
057            case simple_object_name_t:
058                boolean getValueFromVar = false;
059                TVariable symbolVariable =  TSymbolTableManager.searchSymbolVariable(frameStack,plainText);
060                if (symbolVariable != null){
061                    if (symbolVariable.getVariableStr() != null){
062                        plainText = symbolVariable.getVariableStr();
063                        expr.setPlainTextLineNo( symbolVariable.getLineNo());
064                        expr.setPlainTextColumnNo(symbolVariable.getColumnNo());
065                        getValueFromVar = true;
066                        // variableStr is only recorded for resolved string values,
067                        // so a successful lookup carries a real value
068                        expr.setVal(plainText);
069                        expr.setValPartial(symbolVariable.isVariableStrPartial());
070                        //System.out.println("variable name:"+symbolVariable.getName()+", value: "+plainText);
071                    }
072                }
073                if (!getValueFromVar){
074                    plainText = plainText.replace(".", "_");
075                }
076
077//                if (expr.getObjectOperand().getDbObjectType() == EDbObjectType.variable){
078//                }else {
079//                    plainText = plainText.replace(".", "_");
080//                }
081
082                break;
083            case case_t:
084                TExpression resultExpr = expr.getCaseExpression().getWhenClauseItemList().getWhenClauseItem(0).getReturn_expr();
085                resultExpr.evaluate(frameStack,sqlStatement);
086                plainText = resultExpr.getPlainText();
087                expr.setVal(resultExpr.getVal());
088                expr.setValPartial(resultExpr.isValPartial());
089
090                //System.out.println(plainText);
091                break;
092            default:
093                break;
094        }
095
096          expr.setPlainText(plainText);
097    }
098
099    public boolean exprVisit(TParseTreeNode pNode, boolean isLeafNode){
100        if (isLeafNode){
101            evaluateLeafExpr(((TExpression)pNode));
102            expressionStack.push((TExpression)pNode);
103        }
104
105        TExpression expr = (TExpression)pNode;
106        switch (expr.getExpressionType()){
107            case concatenate_t:
108            case arithmetic_plus_t:
109                TExpression expr1 = expressionStack.pop();
110                TExpression expr2 = expressionStack.pop();
111                ((TExpression)pNode).setPlainText(expr2.getPlainText() + expr1.getPlainText());
112                // a concatenation carries a real string value when at least one
113                // operand resolved to one; unresolved operands stay in the text
114                // as placeholder identifiers (e.g. 'WHERE id = ' || v_id) and
115                // mark the value as partially resolved
116                if (expr1.getVal() != null || expr2.getVal() != null){
117                    ((TExpression)pNode).setVal(expr2.getPlainText() + expr1.getPlainText());
118                    ((TExpression)pNode).setValPartial(expr1.getVal() == null || expr2.getVal() == null
119                            || expr1.isValPartial() || expr2.isValPartial());
120                }
121                expressionStack.push((TExpression)pNode);
122                break;
123        }
124        return true;
125    };
126
127}
128
129class columnVisitor extends TParseTreeVisitor {
130    ArrayList<TObjectName> columns;
131
132    public columnVisitor( ArrayList<TObjectName> columnsInsideExpression){
133        columns = columnsInsideExpression;
134    }
135
136    @Override
137    public void preVisit(TObjectName node) {
138        if (node.getDbObjectType() == EDbObjectType.column){
139            columns.add(node);
140        }
141    }
142
143//    public boolean exprVisit(TParseTreeNode pNode,boolean isLeafNode){
144//        TExpression expr = (TExpression)pNode;
145//        switch (expr.getExpressionType()){
146//            case simple_object_name_t:
147//                columns.add(expr.getObjectOperand());
148//                break;
149//            case function_t:
150//                if (expr.getFunctionCall().getArgs() != null){
151//                    for(int i=0;i<expr.getFunctionCall().getArgs().size();i++){
152//                        ArrayList<TObjectName>  list = expr.getFunctionCall().getArgs().getExpression(i).getColumnsInsideExpression();
153//                        for(int j=0;j<list.size();j++){
154//                            columns.add(list.get(j));
155//                        }
156//                    }
157//                }
158//                break;
159//            default:
160//                break;
161//        }
162//        return true;
163//    };
164}
165
166
167/**
168 * @deprecated As of v2.0.5.6, use class ColumnVisitor in package demos.columnInWhereClause instead.
169 */
170class searchColumnVisitor implements IExpressionVisitor {
171    private TExpressionList _resultList;
172    private String _targetColumn;
173
174    public searchColumnVisitor(String targetColumn, TExpressionList resultList){
175        _resultList = resultList;
176        _targetColumn = targetColumn;
177    }
178
179    public boolean exprVisit(TParseTreeNode pNode,boolean isLeafNode){
180        TExpression expr = (TExpression)pNode;
181        if (expr.getExpressionType() == EExpressionType.simple_object_name_t){
182            if (_targetColumn.contains(".")){
183                if (SQLUtil.compareIdentifier(expr.dbvendor, ESQLDataObjectType.dotColumn, _targetColumn, expr.getObjectOperand().toString())){
184                    _resultList.addExpression(expr);
185                }
186            }else{
187                if (SQLUtil.sameName(expr.dbvendor, ESQLDataObjectType.dotColumn, _targetColumn, expr.getObjectOperand().getColumnNameOnly())){
188                    _resultList.addExpression(expr);
189                }
190            }
191        }else if ((expr.getExpressionType() == EExpressionType.function_t)&&(expr.getFunctionCall().getArgs() != null)){
192            if (expr.getFunctionCall().getArgs().size() > 0){
193                TExpressionList list1;
194                for(int i=0;i<expr.getFunctionCall().getArgs().size();i++){
195                    list1 = expr.getFunctionCall().getArgs().getExpression(i).searchColumn(_targetColumn);
196                    if (list1.size() > 0){
197                        for(int j=0;j<list1.size();j++){
198                            _resultList.addExpression(list1.getExpression(j));
199                        }
200                    }
201                }
202                //expr.getFunctionCall().getArgs().getExpression(0).
203            }
204        }
205        return true;
206    };
207}
208
209class TFlattenVisitor implements IExpressionVisitor {
210
211    private ArrayList flattedAndOrExprs = new ArrayList();
212
213    public ArrayList getFlattedAndOrExprs() {
214        return flattedAndOrExprs;
215    }
216
217    public boolean exprVisit(TParseTreeNode pNode,boolean isLeafNode){
218        TExpression expr = (TExpression)pNode;
219        if (isLeafNode) flattedAndOrExprs.add(expr);
220        return true;
221    }
222
223}
224
225/**
226* An expression is a combination of one or more values, operators, and SQL functions that evaluates to a value.
227* There are lots of types of expression in this SQL parser, {@link #getExpressionType()} was used to distinguish these types.
228 *
229 * <p>
230 *     OBJECT NAME/CONSTANT/SOURCE TOKEN/FUNCTION CALL
231 *     <ul>
232  *         <li>object name, usually this is a column reference like emp.ename
233  *         <ul>
234   *             <li>type: {@link EExpressionType#simple_object_name_t}</li>
235 *               <li>object name: {@link #getObjectOperand()}</li>
236   *             <li>left operand:  N/A</li>
237   *             <li>right operand: N/A </li>
238   *             <li>operator: N/A </li>
239   *             </ul>
240   *         </li>
241 *         <li>constant
242 *         <ul>
243  *             <li>type: {@link EExpressionType#simple_constant_t}</li>
244*               <li>constant: {@link #getConstantOperand()}</li>
245  *             <li>left operand:  N/A</li>
246  *             <li>right operand: N/A </li>
247  *             <li>operator: N/A </li>
248  *             </ul>
249  *         </li>
250 *         <li>sourcetoken
251 *         <ul>
252  *             <li>type: {@link EExpressionType#simple_source_token_t}</li>
253*               <li>source token: {@link #getSourcetokenOperand()}</li>
254  *             <li>left operand:  N/A</li>
255  *             <li>right operand: N/A </li>
256  *             <li>operator: N/A </li>
257  *             </ul>
258  *         </li>
259 *         <li>function call
260 *         <ul>
261  *             <li>type: {@link EExpressionType#function_t}</li>
262*               <li>funcation call: {@link #getFunctionCall()}</li>
263  *             <li>left operand:  N/A</li>
264  *             <li>right operand: N/A </li>
265  *             <li>operator: N/A </li>
266  *             </ul>
267  *         </li>
268  *         </ul>
269 *
270 *     UNARY
271 *     <ul>
272 *         <li>  + expr1
273 *         <ul>
274  *             <li>type: {@link EExpressionType#unary_plus_t}</li>
275  *             <li>left operand:  N/A</li>
276  *             <li>right operand: getRightOperand</li>
277  *             <li>operator: {@link #getOperatorToken()}</li>
278  *             </ul>
279  *         </li>
280 *         <li>  - expr1
281 *         <ul>
282  *             <li>type: {@link EExpressionType#unary_minus_t}</li>
283 *             <li>left operand:  N/A</li>
284 *             <li>right operand: getRightOperand</li>
285 *             <li>operator: {@link #getOperatorToken()}</li>
286  *             </ul>
287  *         </li>
288 *         <li>  expr1 !
289 *         <ul>
290  *             <li>type: {@link EExpressionType#unary_factorial_t}</li>
291 *             <li>left operand:  {@link #getLeftOperand()}</li>
292 *             <li>right operand: N/A</li>
293 *             <li>operator: {@link #getOperatorToken()}</li>
294  *             </ul>
295  *         </li>
296 *         <li>  ~ expr1
297 *         <ul>
298  *             <li>type: {@link EExpressionType#unary_bitwise_not_t}</li>
299 *             <li>left operand:  N/A</li>
300 *             <li>right operand: {@link #getRightOperand()}</li>
301 *             <li>operator: {@link #getOperatorToken()}</li>
302  *             </ul>
303  *         </li>
304 *         <li>  @ expr1
305 *         <ul>
306  *             <li>type: {@link EExpressionType#unary_absolutevalue_t}</li>
307 *             <li>left operand:  N/A</li>
308 *             <li>right operand: {@link #getRightOperand()}</li>
309 *             <li>operator: {@link #getOperatorToken()}</li>
310  *             </ul>
311  *         </li>
312 *         <li>  |/ expr1
313 *         <ul>
314  *             <li>type: {@link EExpressionType#unary_squareroot_t}</li>
315 *             <li>left operand:  N/A</li>
316 *             <li>right operand: {@link #getRightOperand()}</li>
317 *             <li>operator: {@link #getOperatorToken()}</li>
318  *             </ul>
319  *         </li>
320 *         <li>  ||/ expr1
321 *         <ul>
322  *             <li>type: {@link EExpressionType#unary_cuberoot_t}</li>
323 *             <li>left operand:  N/A</li>
324 *             <li>right operand: {@link #getRightOperand()}</li>
325 *             <li>operator: {@link #getOperatorToken()}</li>
326  *             </ul>
327  *         </li>
328 *         <li>  !! expr1
329 *         <ul>
330  *             <li>type: {@link EExpressionType#unary_factorialprefix_t}</li>
331 *             <li>left operand:  N/A</li>
332 *             <li>right operand: {@link #getRightOperand()}</li>
333 *             <li>operator: {@link #getOperatorToken()}</li>
334  *             </ul>
335  *         </li>
336 *         <li>  Oracle: PRIOR expr1
337 *         <ul>
338  *             <li>type: {@link EExpressionType#unary_prior_t}</li>
339 *             <li>left operand:  N/A</li>
340 *             <li>right operand: getRightOperand</li>
341 *             <li>operator: {@link #getOperatorToken()}</li>
342  *             </ul>
343  *         </li>
344 *         <li>  Oracle: CONNECT_BY_ROOT expr1
345 *         <ul>
346  *             <li>type: {@link EExpressionType#unary_connect_by_root_t}</li>
347 *             <li>left operand:  N/A</li>
348 *             <li>right operand: getRightOperand</li>
349 *             <li>operator: {@link #getOperatorToken()}</li>
350  *             </ul>
351  *         </li>
352 *         <li>  MySQL: BINARY expr1
353 *         <ul>
354  *             <li>type: {@link EExpressionType#unary_prior_t}</li>
355 *             <li>left operand:  N/A</li>
356 *             <li>right operand: getRightOperand</li>
357 *             <li>operator: {@link #getOperatorToken()}</li>
358  *             </ul>
359  *         </li>
360 *         </ul>
361 *
362 *     ARITHMETIC
363 *     <ul>
364 *         <li>Addition: expr1 + expr2
365 *         <ul>
366 *             <li>type: {@link EExpressionType#arithmetic_plus_t}</li>
367 *             <li>left operand:  {@link #getLeftOperand()}</li>
368 *             <li>right operand: {@link #getRightOperand()} </li>
369 *             <li>operator: {@link #getOperatorToken()} </li>
370 *             </ul>
371 *         </li>
372 *         <li>Subtraction: expr1 - expr2
373 *         <ul>
374 *             <li>type: {@link EExpressionType#arithmetic_minus_t}</li>
375 *             <li>left operand:  {@link #getLeftOperand()}</li>
376 *             <li>right operand: {@link #getRightOperand()} </li>
377 *             <li>operator: {@link #getOperatorToken()} </li>
378 *             </ul>
379 *         </li>
380 *         <li>Multiplication: expr1 * expr2
381 *         <ul>
382 *             <li>type: {@link EExpressionType#arithmetic_times_t}</li>
383 *             <li>left operand:  {@link #getLeftOperand()}</li>
384 *             <li>right operand: {@link #getRightOperand()} </li>
385 *             <li>operator: {@link #getOperatorToken()} </li>
386 *             </ul>
387 *         </li>
388 *         <li>Division: expr1 / expr2
389 *         <ul>
390 *             <li>type: {@link EExpressionType#arithmetic_divide_t}</li>
391 *             <li>left operand:  {@link #getLeftOperand()}</li>
392 *             <li>right operand: {@link #getRightOperand()} </li>
393 *             <li>operator: {@link #getOperatorToken()} </li>
394 *             </ul>
395 *         </li>
396 *         <li>Modula: expr1 % expr2
397 *         <ul>
398 *             <li>type: {@link EExpressionType#arithmetic_modulo_t}</li>
399 *             <li>left operand:  {@link #getLeftOperand()}</li>
400 *             <li>right operand: {@link #getRightOperand()} </li>
401 *             <li>operator: {@link #getOperatorToken()} </li>
402 *             </ul>
403 *         </li>
404 *         <li>exponentiate: expr1 ^ expr2
405 *         <ul>
406 *             <li>type: {@link EExpressionType#exponentiate_t}</li>
407 *             <li>left operand:  {@link #getLeftOperand()}</li>
408 *             <li>right operand: {@link #getRightOperand()} </li>
409 *             <li>operator: {@link #getOperatorToken()} </li>
410 *             </ul>
411 *         </li>
412 *         <li>sql server 2008 +=,-=,*=,/=,%=: expr1 [+=|-=|*=|/=|%=] expr2
413 *         <ul>
414 *             <li>type: {@link EExpressionType#arithmetic_compound_operator_t}</li>
415 *             <li>left operand:  {@link #getLeftOperand()}</li>
416 *             <li>right operand: {@link #getRightOperand()} </li>
417 *             <li>operator: {@link #getOperatorToken()} </li>
418 *             </ul>
419 *         </li>
420 *     </uL>
421 *
422 *     LOGICAL
423 *     <ul>
424 *         <li>expr1 AND|&amp;&amp; expr2</li>
425  *             <li>type: {@link EExpressionType#logical_and_t}</li>
426  *             <li>left operand:  {@link #getLeftOperand()}</li>
427  *             <li>right operand: {@link #getRightOperand()} </li>
428  *             <li>operator: {@link #getOperatorToken()} </li>
429  *
430 *         <li>expr1 OR | || expr2
431 *         <ul>
432  *             <li>type: {@link EExpressionType#logical_or_t}</li>
433  *             <li>left operand:  {@link #getLeftOperand()}</li>
434  *             <li>right operand: {@link #getRightOperand()} </li>
435  *             <li>operator: {@link #getOperatorToken()} </li>
436  *             </ul>
437  *         </li>
438 *         <li>expr1 XOR expr2
439 *         <ul>
440  *             <li>type: {@link EExpressionType#logical_xor_t}</li>
441  *             <li>left operand:  {@link #getLeftOperand()}</li>
442  *             <li>right operand: {@link #getRightOperand()} </li>
443  *             <li>operator: {@link #getOperatorToken()} </li>
444  *             </ul>
445  *         </li>
446 *         <li>NOT|! expr1
447 *         <ul>
448  *             <li>type: {@link EExpressionType#logical_not_t}</li>
449  *             <li>left operand:  N/A</li>
450  *             <li>right operand: {@link #getRightOperand()} </li>
451  *             <li>operator: {@link #getOperatorToken()} </li>
452  *             </ul>
453  *         </li>
454 *         </ul>
455 *
456 *     ASSIGNMENT
457 *     <ul>
458 *         <li>ASSIGNMENT: expr1 [:=|=] expr2
459 *         <ul>
460  *             <li>type: {@link EExpressionType#assignment_t}</li>
461  *             <li>left operand:  {@link #getLeftOperand()}</li>
462  *             <li>right operand: {@link #getRightOperand()} </li>
463  *             <li>operator: {@link #getOperatorToken()} </li>
464  *             </ul>
465  *         </li>
466 *         </ul>
467 *
468 *     CONCATENATE
469 *     <ul>
470 *         <li>CONCATENATE: expr1 || expr2
471 *         <ul>
472  *             <li>type: {@link EExpressionType#concatenate_t}</li>
473  *             <li>left operand:  {@link #getLeftOperand()}</li>
474  *             <li>right operand: {@link #getRightOperand()} </li>
475  *             <li>operator: {@link #getOperatorToken()} </li>
476  *             </ul>
477  *         </li>
478 *         </ul>
479 *
480 *     AT TIME ZONE
481 *     <ul>
482 *         <li>expr1 at time zone expr2
483 *         <ul>
484  *             <li>type: {@link EExpressionType#at_time_zone_t}</li>
485  *             <li>left operand:  {@link #getLeftOperand()}</li>
486  *             <li>right operand: {@link #getRightOperand()} </li>
487  *             <li>operator: N/A</li>
488  *             </ul>
489  *         </li>
490 *         </ul>
491 *
492 *     AT LOCAL
493 *     <ul>
494 *         <li>expr1 at local
495 *         <ul>
496  *             <li>type: {@link EExpressionType#at_local_t}</li>
497  *             <li>left operand:  {@link #getLeftOperand()}</li>
498  *             <li>right operand: N/A </li>
499  *             <li>operator: N/A</li>
500  *             </ul>
501  *         </li>
502 *         </ul>
503 *
504 *     BITWISE
505 *     <ul>
506 *         <li>Bitwise and : expr1 &amp; expr2
507 *         <ul>
508  *             <li>type: {@link EExpressionType#bitwise_and_t}</li>
509  *             <li>left operand:  {@link #getLeftOperand()}</li>
510  *             <li>right operand: {@link #getRightOperand()} </li>
511  *             <li>operator: {@link #getOperatorToken()} </li>
512  *             </ul>
513  *         </li>
514 *         <li>Bitwise or : expr1 | expr2
515 *         <ul>
516  *             <li>type: {@link EExpressionType#bitwise_or_t}</li>
517  *             <li>left operand:  {@link #getLeftOperand()}</li>
518  *             <li>right operand: {@link #getRightOperand()} </li>
519  *             <li>operator: {@link #getOperatorToken()} </li>
520  *             </ul>
521  *         </li>
522 *         <li>Bitwise exclusive or : expr1 ^ expr2
523 *         <ul>
524  *             <li>type: {@link EExpressionType#bitwise_exclusive_or_t}</li>
525  *             <li>left operand:  {@link #getLeftOperand()}</li>
526  *             <li>right operand: {@link #getRightOperand()} </li>
527  *             <li>operator: {@link #getOperatorToken()} </li>
528  *             </ul>
529  *         </li>
530 *         <li>Bitwise xor : expr1 ^ expr2
531 *         <ul>
532  *             <li>type: {@link EExpressionType#bitwise_xor_t}</li>
533  *             <li>left operand:  {@link #getLeftOperand()}</li>
534  *             <li>right operand: {@link #getRightOperand()} </li>
535  *             <li>operator: {@link #getOperatorToken()} </li>
536  *             </ul>
537  *         </li>
538 *         <li>Bitwise shift left : expr1 &lt;&lt; expr2
539 *         <ul>
540  *             <li>type: {@link EExpressionType#bitwise_shift_left_t}</li>
541  *             <li>left operand:  {@link #getLeftOperand()}</li>
542  *             <li>right operand: {@link #getRightOperand()} </li>
543  *             <li>operator: {@link #getOperatorToken()} </li>
544  *             </ul>
545  *         </li>
546 *         <li><pre>Bitwise shift right : expr1 &gt;&gt; expr2</pre>
547 *         <ul>
548  *             <li>type: {@link EExpressionType#bitwise_shift_right_t}</li>
549  *             <li>left operand:  {@link #getLeftOperand()}</li>
550  *             <li>right operand: {@link #getRightOperand()} </li>
551  *             <li>operator: {@link #getOperatorToken()} </li>
552  *             </ul>
553  *         </li>
554 *         </ul>
555 *
556 *     SUBQUERY
557 *     <ul>
558 *         <li> A scalar subquery expression is a subquery that returns exactly one column value from one row.
559 *         <ul>
560  *             <li>type: {@link EExpressionType#subquery_t}</li>
561 *              <li>subquery: {@link #getSubQuery()} </li>
562  *             <li>left operand:  N/A</li>
563  *             <li>right operand: N/A </li>
564  *             <li>operator: N/A</li>
565  *             </ul>
566  *         </li>
567 *         </ul>
568 *
569 *     EXPRESSION WITH PARENTHESIS
570 *     <ul>
571 *         <li> ( expr1 )
572 *         <ul>
573  *             <li>type: {@link EExpressionType#parenthesis_t}</li>
574  *             <li>left operand is expr1:  {@link #getLeftOperand()}</li>
575  *             <li>right operand: N/A </li>
576  *             <li>operator: use {@link #getStartToken()} to get ( and {@link #getEndToken()} to get )</li>
577  *             </ul>
578  *         </li>
579 *         </ul>
580 *
581 *     LIST EXPRESSION
582 *     <ul>
583 *         <li>An expression list inside parenthesis like (expr,expr,...),
584 *         or one or more set of expressions: ((expr1,expr2,...),(expr1,expr2,...),(expr1,expr2,...)...)
585 *         <ul>
586  *             <li>type: {@link EExpressionType#list_t}</li>
587 *              <li>expr list: {@link #getExprList()}, may return null when expression list in syntax like this: () </li>
588  *             <li>left operand:  N/A</li>
589  *             <li>right operand: N/A </li>
590  *             <li>operator: open parenthsis ( can be fetched via {@link #getStartToken()},
591 *             close parenthesis ) can be fetched via {@link #getEndToken()} </li>
592  *             </ul>
593  *         </li>
594 *         </ul>
595 *
596 *    COLLECTION CONSTRUCTORS (informix)
597 *    <ul>
598 *        <li>Use a collection constructor to specify values for a collection column.
599 *        SET|MULTISET|LIST { epxr_list }
600 *          <ul>
601 *             <li>type: {@link EExpressionType#collection_constructor_set_t}</li>
602 *             <li>type: {@link EExpressionType#collection_constructor_multiset_t}</li>
603 *             <li>type: {@link EExpressionType#collection_constructor_list_t}</li>
604 *              <li>expr list: {@link #getExprList()}, may return null when expression list in syntax like this: () </li>
605 *             <li>left operand:  N/A</li>
606 *             <li>right operand: N/A </li>
607 *          </ul>
608 *        </li>
609 *
610 *
611 *    </ul>
612 *
613 *     GROUP EXPRESSION,  @deprecated As of v1.4.3.3
614 *     <ul>
615 *         <li>
616  *         </li>
617 *         </ul>
618 *
619 *     COMPARISON
620 *     <ul>
621 *         <li>A <b>simple comparison condition</b> specifies a comparison with expressions or subquery results.
622 *         <br>expr1 EQUAL|NOT_EQUAL|LESS_THAN|GRREAT_THAN|LESS_EQUAL_THAN|GREATE_EQUAL_THAN expr2,
623 *         or, (expr_list) EQUAL|NOT_EQUAL (subquery)
624 *             <ul>
625 *             <li>type: {@link EExpressionType#simple_comparison_t}</li>
626 *             <li>left operand:  {@link #getLeftOperand()}</li>
627 *             <li>right operand: {@link #getRightOperand()} </li>
628 *             <li>operator: {@link #getOperatorToken()}</li>
629 *             </ul>
630 *         </li>
631 *         <li>A <b>group comparison condition</b> specifies a comparison with any or all members
632 *         in a list or subquery.
633 *         <br>expr EQUAL|NOT_EQUAL|LESS_THAN|GRREAT_THAN|LESS_EQUAL_THAN|GREATE_EQUAL_THAN ANY|SOME|ALL (expr_list|subquery),
634 *         or, (expr_list) EQUAL|NOT_EQUAL ANY|SOME|ALL (expr_list|subquery)
635 *             <ul>
636 *             <li>type: {@link EExpressionType#group_comparison_t}</li>
637 *             <li>left operand:  {@link #getLeftOperand()}</li>
638 *             <li>right operand: {@link #getRightOperand()} </li>
639 *             <li>operator: {@link #getOperatorToken()}</li>
640 *             <li> ANY|SOME|ALL: {@link #getQuantifier()}</li>
641 *             </ul>
642 *         </li>
643 *         </ul>
644 *
645 *     IN
646 *     <ul>
647 *         <li>(expr|expr_list) |NOT] IN (expr_list)|(subquery)|expr
648 *         <ul>
649  *             <li>type: {@link EExpressionType#in_t}</li>
650 *             <li>left operand:  {@link #getLeftOperand()}</li>
651 *             <li>right operand: {@link #getRightOperand()} </li>
652  *            <li>operator is IN: {@link #getOperatorToken()} </li>
653 *             <li>NOT keyword: {@link #getNotToken()} </li>
654  *             </ul>
655  *         </li>
656 *         </ul>
657 *
658 *     CASE
659 *     <ul>
660 *         <li>case expression,let you use IF ... THEN ... ELSE logic in SQL statements without having to invoke procedures.
661 *         <ul>
662  *             <li>type: {@link EExpressionType#case_t}</li>
663 *              <li> case expression: {@link #getCaseExpression()}}</li>
664  *             <li>left operand:  N/A</li>
665  *             <li>right operand: N/A </li>
666  *             <li>operator: N/A </li>
667  *             </ul>
668  *         </li>
669 *         </ul>
670 *
671 *     CURSOR
672 *     <ul>
673 *         <li>CURSOR subquery
674 *         <ul>
675  *             <li>type: {@link EExpressionType#cursor_t}</li>
676 *              <li>subquery: {@link #getSubQuery()}</li>
677  *             <li>left operand:  N/A</li>
678  *             <li>right operand: N/A </li>
679  *             <li>operator: CURSOR can be fetched via {@link #getStartToken()} </li>
680  *             </ul>
681  *         </li>
682 *         </ul>
683 *
684 *     PATTERN MATCHING
685 *     <ul>
686 *         <li>expr1 [NOT] [LIKE|ILIKE|RLIKE|REGEXP|SIMILAR TO] [ALL|ANY|SOME]expr2 [ESCAPE expr3]
687 *         <ul>
688  *             <li>type: {@link EExpressionType#pattern_matching_t}</li>
689  *             <li>left operand:  {@link #getLeftOperand()}</li>
690  *             <li>right operand:{@link #getRightOperand()} </li>
691 *              <li>expr3: {@link #getLikeEscapeOperand()} </li>
692  *             <li>operator: {@link #getOperatorToken()}</li>
693 *              <li>NOT keyword: {@link #getNotToken()}</li>
694 *              <li>ALL|ANY|SOME keyword: {@link #getQuantifier()}</li>
695 *              <li>ESCAPE keyword: N/A</li>
696  *             </ul>
697  *         </li>
698 *         </ul>
699 *
700 *     NULL
701 *     <ul>
702 *         <li>expr ISNULL|NOTNULL|IS [NOT] NULL
703 *         <ul>
704  *             <li>type: {@link EExpressionType#null_t}</li>
705  *             <li>left operand:  {@link #getLeftOperand()}</li>
706  *             <li>right operand: N/A </li>
707  *             <li>operator is NULL: {@link #getOperatorToken()}</li>
708 *              <li>NOT keyword: {@link #getNotToken()}</li>
709  *             </ul>
710  *         </li>
711 *         </ul>
712 *
713 *     BETWEEN
714 *     <ul>
715 *         <li>expr1 [NOT] BETWEEN expr2 AND expr3
716 *         <ul>
717  *             <li>type: {@link EExpressionType#between_t}</li>
718 *              <li>expr1:  {@link #getBetweenOperand()}</li>
719  *             <li>expr2:  {@link #getLeftOperand()}</li>
720  *             <li>expr3: {@link #getRightOperand()} </li>
721  *             <li>operator is BETWEEN: {@link #getOperatorToken()}</li>
722 *              <li>NOT keyword: {@link #getNotToken()}</li>
723  *             </ul>
724  *         </li>
725 *         </ul>
726 *
727 *     EXISTS
728 *     <ul>
729 *         <li>EXISTS (subquery)
730 *         <ul>
731  *             <li>type: {@link EExpressionType#exists_t}</li>
732 *              <li>left operand:  N/A</li>
733  *             <li>right operand: N/A</li>
734  *             <li>subquery: {@link #getSubQuery()} </li>
735  *             <li>EXISTS: {@link #getStartToken()}</li>
736  *             </ul>
737  *         </li>
738 *         </ul>
739 *
740 *    IS UNKNOWN
741 *     <ul>
742 *         <li> expr1 IS [NOT] UNKNOWN
743 *         <ul>
744  *             <li>type: {@link EExpressionType#is_unknown_t}</li>
745 *             <li>left operand:  {@link #getLeftOperand()}</li>
746 *             <li>right operand: N/A </li>
747  *             <li>operator: {@link #getOperatorToken()}</li>
748 *             <li>NOT keyword: {@link #getNotToken()}</li>
749  *             </ul>
750  *         </li>
751 *         </ul>
752 *
753 *    IS TRUE
754 *     <ul>
755 *         <li> expr1 IS [NOT] TRUE
756 *         <ul>
757  *             <li>type: {@link EExpressionType#is_true_t}</li>
758 *             <li>left operand:  {@link #getLeftOperand()}</li>
759 *             <li>right operand: N/A </li>
760  *             <li>operator: {@link #getOperatorToken()}</li>
761 *             <li>NOT keyword: {@link #getNotToken()}</li>
762  *             </ul>
763  *         </li>
764 *         </ul>
765 *
766 *    IS FALSE
767 *     <ul>
768 *         <li> expr1 IS [NOT] FALSE
769 *         <ul>
770  *             <li>type: {@link EExpressionType#is_false_t}</li>
771 *             <li>left operand:  {@link #getLeftOperand()}</li>
772 *             <li>right operand: N/A </li>
773  *             <li>operator: {@link #getOperatorToken()}</li>
774 *             <li>NOT keyword: {@link #getNotToken()}</li>
775  *             </ul>
776  *         </li>
777 *         </ul>
778 *
779 *     DAY TO SECOND
780 *     <ul>
781 *         <li>expr DAY [( integer )] TO SECOND [( integer )]
782 *         <ul>
783  *             <li>type: {@link EExpressionType#day_to_second_t}</li>
784  *             <li>left operand:  {@link #getLeftOperand()}</li>
785  *             <li>right operand: N/A </li>
786  *             <li>operator: N/A</li>
787  *             </ul>
788  *         </li>
789 *         </ul>
790 *
791 *     YEAR TO MONTH
792 *     <ul>
793 *         <li>expr YEAR [( integer )] TO MONTH
794 *         <ul>
795  *             <li>type: {@link EExpressionType#year_to_month_t}</li>
796  *             <li>left operand:  {@link #getLeftOperand()}</li>
797  *             <li>right operand: N/A </li>
798  *             <li>operator: N/A</li>
799  *             </ul>
800  *         </li>
801 *         </ul>
802 *
803 *     INTERVAL(teradata)
804 *     <ul>
805 *         <li>( date_time_expression date_time_term ) start TO end
806 *         <ul>
807  *             <li>type: {@link EExpressionType#interval_t}</li>
808 *              <li>date_time_expression: {@link #getIntervalExpr()} </li>
809  *             <li>left operand:  N/A</li>
810  *             <li>right operand: N/A </li>
811  *             <li>operator: N/A</li>
812  *             </ul>
813  *         </li>
814 *         </ul>
815 *
816 *     NEW STRUCTURED TYPE
817 *     <ul>
818 *         <li>NEW function_call
819 *         <ul>
820  *             <li>type: {@link EExpressionType#new_structured_type_t}</li>
821 *              <li>function_call: {@link #getFunctionCall()} </li>
822  *             <li>left operand:  N/A</li>
823  *             <li>right operand: N/A </li>
824  *             <li>operator: N/A</li>
825  *             </ul>
826  *         </li>
827 *         </ul>
828 *
829 *     NEW VARIANT_TYPE
830 *     <ul>
831 *         <li>NEW VARIANT_TYPE ( type_argument_list )
832 *         <ul>
833  *             <li>type: {@link EExpressionType#new_variant_type_t}</li>
834 *              <li>type_argument_list: {@link #getNewVariantTypeArgumentList()} </li>
835  *             <li>left operand:  N/A</li>
836  *             <li>right operand: N/A </li>
837  *             <li>operator: N/A</li>
838  *             </ul>
839  *         </li>
840 *         </ul>
841 *
842 *     LDIFF,RDIFF,P_INTERSECT,P_NORMALIZE
843 *     <ul>
844 *         <li> expr1 LDIFF|RDIFF|P_INTERSECT|P_NORMALIZE expr2
845 *         <ul>
846  *             <li>type: {@link EExpressionType#new_variant_type_t}</li>
847 *             <li>left operand:  {@link #getLeftOperand()}</li>
848 *             <li>right operand: {@link #getRightOperand()} </li>
849  *             <li>operator: {@link #getOperatorToken()}</li>
850  *             </ul>
851  *         </li>
852 *         </ul>
853 *
854 *    UNTIL CHANGED
855 *     <ul>
856 *         <li> expr1 IS [NOT] UNTIL_CHANGED
857 *         <ul>
858  *             <li>type: {@link EExpressionType#new_variant_type_t}</li>
859 *             <li>left operand:  {@link #getLeftOperand()}</li>
860 *             <li>right operand: N/A </li>
861  *             <li>operator: {@link #getOperatorToken()}</li>
862 *             <li>NOT keyword: {@link #getNotToken()}</li>
863  *             </ul>
864  *         </li>
865 *         </ul>
866 *
867 *     LEFT SHIFT
868 *     <ul>
869 *         <li><pre>expr1 &lt;&lt; expr2</pre>
870 *         <ul>
871  *             <li>type: {@link EExpressionType#left_shift_t}</li>
872  *             <li>left operand:  {@link #getLeftOperand()}</li>
873  *             <li>right operand: {@link #getRightOperand()} </li>
874  *             <li>operator: {@link #getOperatorToken()} </li>
875  *             </ul>
876  *         </li>
877 *         </ul>
878 *
879 *     RIGHT SHIFT
880 *     <ul>
881 *         <li>expr1 &gt;&gt; expr2
882 *         <ul>
883  *             <li>type: {@link EExpressionType#right_shift_t}</li>
884  *             <li>left operand:  {@link #getLeftOperand()}</li>
885  *             <li>right operand: {@link #getRightOperand()} </li>
886  *             <li>operator: {@link #getOperatorToken()} </li>
887  *             </ul>
888  *         </li>
889 *         </ul>
890 *
891 *    IS DOCUMENT
892 *     <ul>
893 *         <li> expr1 IS [NOT] DOCUMENT
894 *         <ul>
895  *             <li>type: {@link EExpressionType#is_document_t}</li>
896 *             <li>left operand:  {@link #getLeftOperand()}</li>
897 *             <li>right operand: N/A </li>
898  *             <li>operator: {@link #getOperatorToken()}</li>
899 *             <li>NOT keyword: {@link #getNotToken()}</li>
900  *             </ul>
901  *         </li>
902 *         </ul>
903 *
904 *     IS DISTINCT FROM
905 *     <ul>
906 *         <li> expr1 IS [NOT] DISTINCT FROM expr2
907 *         <ul>
908  *             <li>type: {@link EExpressionType#is_distinct_from_t}</li>
909 *             <li>left operand:  {@link #getLeftOperand()}</li>
910 *             <li>right operand: {@link #getRightOperand()} </li>
911  *             <li>operator: {@link #getOperatorToken()}</li>
912 *             <li>NOT keyword: {@link #getNotToken()}</li>
913  *             </ul>
914  *         </li>
915 *         </ul>
916 *
917 *     SQL SERVER left join
918 *     <ul>
919 *         <li> expr1 *= expr2
920 *         <ul>
921  *             <li>type: {@link EExpressionType#left_join_t}</li>
922 *             <li>left operand:  {@link #getLeftOperand()}</li>
923 *             <li>right operand: {@link #getRightOperand()} </li>
924  *            <li>operator: {@link #getOperatorToken()}</li>
925  *             </ul>
926  *         </li>
927 *         </ul>
928 *
929 *     SQL SERVER right join
930 *     <ul>
931 *         <li> expr1 =* expr2
932 *         <ul>
933  *             <li>type: {@link EExpressionType#right_join_t}</li>
934 *             <li>left operand:  {@link #getLeftOperand()}</li>
935 *             <li>right operand: {@link #getRightOperand()} </li>
936  *            <li>operator: {@link #getOperatorToken()}</li>
937  *             </ul>
938  *         </li>
939 *         </ul>
940 *
941 *     COLLATE
942 *     <ul>
943 *         <li> expr1 COLLATE expr2
944 *         <ul>
945  *             <li>type: {@link EExpressionType#collate_t}</li>
946 *             <li>left operand:  {@link #getLeftOperand()}</li>
947 *             <li>right operand: {@link #getRightOperand()} </li>
948  *             <li>operator: {@link #getOperatorToken()}</li>
949 *             <li>NOT keyword: {@link #getNotToken()}</li>
950  *             </ul>
951  *         </li>
952 *         </ul>
953 *
954 *     MEMBER OF
955 *     <ul>
956 *         <li> expr1 MEMBER OF expr2
957 *         <ul>
958  *             <li>type: {@link EExpressionType#member_of_t}</li>
959 *             <li>left operand:  {@link #getLeftOperand()}</li>
960 *             <li>right operand: {@link #getRightOperand()} </li>
961  *             <li>operator: {@link #getOperatorToken()}</li>
962  *             </ul>
963  *         </li>
964 *         </ul>
965 *
966 *     NEXT VALUE FOR
967 *     <ul>
968 *         <li> <pre>NEXT VALUE FOR &lt;sequence name&gt;, or NEXT &lt;integer expression&gt;VALUE FOR &lt;sequence name&gt;</pre></li>
969  *             <li>type: {@link EExpressionType#next_value_for_t}</li>
970 *             <li>sequence name: {@link #getSequenceName()}   </li>
971 *             <li>over_clause : {@link #getOver_clause()}} </li>
972 *             <li>left operand(integer expression):  {@link #getLeftOperand()}</li>
973 *         </ul>
974 *
975 *     REF ARROW(named parameters in function call)
976 *     <ul>
977 *         <li> expr1 =&gt; expr2
978 *         <ul>
979  *             <li>type: {@link EExpressionType#ref_arrow_t}</li>
980  *             <li>left operand:  {@link #getLeftOperand()}</li>
981  *             <li>right operand: {@link #getRightOperand()} </li>
982  *             <li>operator: {@link #getOperatorToken()} </li>
983  *             </ul>
984  *         </li>
985 *         </ul>
986 *
987 *     TYPECAST
988 *     <ul>
989 *         <li> expr1 TYPECAST typename
990 *         <ul>
991  *             <li>type: {@link EExpressionType#typecast_t}</li>
992 *              <li>typename: {@link #getTypeName()}</li>
993  *             <li>left operand:  {@link #getLeftOperand()}</li>
994  *             <li>right operand: N/A </li>
995  *             <li>operator: {@link #getOperatorToken()} </li>
996  *         </ul>
997  *         </li>
998 *     </ul>
999 *
1000 *     MULTISET
1001 *     <ul>
1002 *         <li>MULTISET subquery
1003 *         <ul>
1004  *             <li>type: {@link EExpressionType#multiset_t}</li>
1005 *              <li>subquery: {@link #getSubQuery()}</li>
1006  *             <li>left operand:  N/A</li>
1007  *             <li>right operand: N/A </li>
1008  *             <li>operator: MULTISET can be fetched via {@link #getStartToken()} </li>
1009  *             </ul>
1010  *         </li>
1011 *         </ul>
1012 *
1013 *     FLOATING POINT
1014 *     <ul>
1015 *         <li>expr is [NOT] NAN|INFINITE
1016 *         <ul>
1017  *             <li>type: {@link EExpressionType#floating_point_t}</li>
1018  *             <li>left operand:  {@link #getLeftOperand()}</li>
1019  *             <li>right operand: N/A </li>
1020  *             <li>operator is IS: {@link #getOperatorToken()}</li>
1021 *              <li>NOT keyword: {@link #getNotToken()}</li>
1022  *             </ul>
1023  *         </li>
1024 *         </ul>
1025 *
1026 *     ROW CONSTRUCTOR
1027 *     <ul>
1028 *         <li>ROW ( expr_list )
1029 *         <ul>
1030  *             <li>type: {@link EExpressionType#row_constructor_t}</li>
1031 *              <li>expr_list:  {@link #getExprList()}</li>
1032  *             <li>left operand:  N/A</li>
1033  *             <li>right operand: N/A </li>
1034  *             <li>operator is ROW: {@link #getStartToken()}</li>
1035  *             </ul>
1036  *         </li>
1037 *         </ul>
1038 *
1039 *     IS OF TYPE
1040 *     <ul>
1041 *         <li>expr is of type ( datatype,...)
1042 *         <ul>
1043  *             <li>type: {@link EExpressionType#is_of_type_t}</li>
1044  *             <li>left operand:  {@link #getLeftOperand()}</li>
1045  *             <li>right operand: N/A </li>
1046  *             <li>operator: N/A</li>
1047  *             </ul>
1048  *         </li>
1049 *         </ul>
1050 *
1051 *     PLACE HOLDER
1052 *     <ul>
1053 *         <li>place holder expression
1054 *         <ul>
1055  *             <li>type: {@link EExpressionType#place_holder_t}</li>
1056  *             <li>left operand:  N/A</li>
1057  *             <li>right operand: N/A </li>
1058  *             <li>operator: N/A</li>
1059  *             </ul>
1060  *         </li>
1061 *         </ul>
1062 *
1063 *     TYPE_CONSTRUCTOR_EXPRESSION
1064 *     <ul>
1065 *         <li>[NEW] type_name( expr_list )
1066 *         <ul>
1067  *             <li>type: {@link EExpressionType#type_constructor_t}</li>
1068  *             <li>type_name(expr_list): {@link #getFunctionCall()}</li>
1069  *             <li>left operand:  N/A</li>
1070  *             <li>right operand: N/A </li>
1071  *             <li>operator: N/A</li>
1072  *             </ul>
1073  *         </li>
1074 *         </ul>
1075 *
1076 *     ARRAY ACCESS
1077 *     <ul>
1078 *         <li>array_name(index1)(index2)(index3)
1079 *         <ul>
1080  *             <li>type: {@link EExpressionType#arrayaccess_t}</li>
1081  *             <li>array_name(index1)(index2)(index3): {@link #getArrayAccess()}</li>
1082  *             <li>left operand:  N/A</li>
1083  *             <li>right operand: N/A </li>
1084  *             <li>operator: N/A</li>
1085  *             </ul>
1086  *         </li>
1087 *         </ul>
1088 *
1089 *     OBJECT ACCESS EXPRESSION
1090 *     <ul>
1091 *         <li>objectExpr.[attributes].method()
1092 *         <ul>
1093  *             <li>type: {@link EExpressionType#object_access_t}</li>
1094  *             <li>objectExpr.[attributes].method(): {@link #getObjectAccess()}</li>
1095  *             <li>left operand:  N/A</li>
1096  *             <li>right operand: N/A </li>
1097  *             <li>operator: N/A</li>
1098  *             </ul>
1099  *         </li>
1100 *      </ul>
1101 *
1102 *     Unknown
1103 *     <ul>
1104 *         <li>expr OPERATOR expr, means this expression was not recognized by SQL parser yet.
1105 *         <ul>
1106  *             <li>type: {@link EExpressionType#unknown_t}</li>
1107  *             <li>left operand: {@link #getLeftOperand()}</li>
1108  *             <li>right operand: {@link #getRightOperand()} </li>
1109  *             <li>operator: {@link #getOperatorToken()}</li>
1110  *             </ul>
1111  *         </li>
1112 *         </ul>
1113 *
1114 *     Unknown unary left
1115 *     <ul>
1116 *         <li>OPERATOR expr, means this expression was not recognized by SQL parser yet.
1117 *         <ul>
1118  *             <li>type: {@link EExpressionType#unary_left_unknown_t}</li>
1119  *             <li>left operand: N/A</li>
1120  *             <li>right operand: {@link #getRightOperand()} </li>
1121  *             <li>operator: {@link #getOperatorToken()}</li>
1122  *             </ul>
1123  *         </li>
1124 *         </ul>
1125 *
1126 *     Unknown unary right
1127 *     <ul>
1128 *         <li> expr OPERATOR, means this expression was not recognized by SQL parser yet.
1129 *         <ul>
1130  *             <li>type: {@link EExpressionType#unary_right_unknown_t}</li>
1131  *             <li>left operand: {@link #getLeftOperand()}</li>
1132  *             <li>right operand: N/A </li>
1133  *             <li>operator: {@link #getOperatorToken()}</li>
1134  *             </ul>
1135  *         </li>
1136 *         </ul>
1137 *
1138 *     ARRAY CONSTRUCTOR
1139 *     <ul>
1140 *         <li>
1141 * An array constructor is an expression that builds an array value using values for its member elements.
1142 * <p> like this: ARRAY[1,2,3+4]
1143 * <p> array element values can be accessed via {@link #getExprList()},
1144 * <p> or {@link #getExprList()} can be null when it is: array[]
1145 * <p>
1146 * <p> It is also possible to construct an array from the results of a subquery like this:
1147 * <p> SELECT ARRAY(SELECT oid FROM pg_proc WHERE proname LIKE 'bytea%');
1148 * <p> thus, subquery can be access via {@link #getSubQuery()}
1149 *         <ul>
1150  *             <li>type: {@link EExpressionType#array_constructor_t}</li>
1151 *             <li>array element values: {@link #getExprList()} </li>
1152 *             <li>subquery: {@link #getSubQuery()}</li>
1153  *             <li>left operand:  N/A</li>
1154  *             <li>right operand: N/A </li>
1155  *             <li>operator: N/A</li>
1156  *             </ul>
1157  *         </li>
1158 *         </ul>
1159 *
1160 *     FIELD SELECTION
1161 *     <ul>
1162 *         <li>
1163 * If an expression yields a value of a composite type (row type), then a specific field of the row can be extracted by writing
1164 * <p> expression.fieldname
1165 * <p> In general the row expression must be parenthesized, but the parentheses can be omitted
1166 * <p> when the expression to be selected from is just a table reference or positional parameter.
1167 * <p> For example:
1168 * <p> mytable.mycolumn
1169 * <p> $1.somecolumn
1170 * <p> (rowfunction(a,b)).col3
1171 * <p>
1172 * <p> (Thus, a qualified column reference is actually just a special case of the field selection syntax.) An important special case is extracting a field from a table column that is of a composite type:
1173 * <p> (compositecol).somefield
1174 * <p> (mytable.compositecol).somefield
1175 * <p> The parentheses are required here to show that compositecol is a column name not a table name,
1176 * <p> or that mytable is a table name not a schema name in the second case.
1177 * <p>
1178 * <p> n a select list, you can ask for all fields of a composite value by writing .*:
1179 * <p> (compositecol).*
1180 * <p>
1181 * <p>
1182 * <p> When expression in following syntax, it will be marked as {@link #fieldSelection}, and check {@link #getFieldName()}
1183 * <p> (rowfunction(a,b)).col3
1184 * <p> (compositecol).somefield
1185 * <p> (mytable.compositecol).somefield
1186 * <p> (compositecol).*
1187 * <p>
1188 * <p> Otherwise, it will be marked as {@link #simpleObjectname}:
1189 * <p> mytable.mycolumn
1190 * <p> $1.somecolumn
1191  *         <ul>
1192  *             <li>type: {@link EExpressionType#fieldselection_t}</li>
1193  *             <li>left operand:  N/A</li>
1194  *             <li>right operand: N/A </li>
1195  *             <li>operator: N/A</li>
1196  *         </ul>
1197 *       </li>
1198 *     </ul>
1199 *
1200 *
1201 * HIVE ARRAY ACCESS
1202 *   <ul>
1203 *     <li>  HIVE field expression syntax like fieldexpr[expr_subscript]
1204 *         <ul>
1205 *             <li>type: {@link EExpressionType#array_access_expr_t}</li>
1206 *             <li>fieldexpr:  {@link #getLeftOperand()}</li>
1207 *             <li>expr_subscript: {@link #getRightOperand()} </li>
1208 *             <li>operator: N/A</li>
1209 *         </ul>
1210*       </li>
1211*     </ul>
1212 *
1213 *
1214 * HIVE FIELD ACCESS
1215 *   <ul>
1216 *     <li>  HIVE field access syntax like fieldexpr.identifier.identifier...
1217 *         <ul>
1218 *             <li>type: {@link EExpressionType#object_access_t}</li>
1219 *             <li>fieldexpr:  {@link #getLeftOperand()}</li>
1220 *             <li>identifier.identifier...: {@link #getFieldList()} </li>
1221 *             <li>operator: N/A</li>
1222 *         </ul>
1223*       </li>
1224*    </ul>
1225*
1226 *     JSON Operators (PostgreSQL)
1227 *
1228 *     <ul>
1229 *         <li> expr1 -&gt; expr2
1230 *         <ul>
1231 *             <li>type: {@link EExpressionType#json_get_object}</li>
1232 *             <li>left operand:  {@link #getLeftOperand()}</li>
1233 *             <li>right operand: {@link #getLeftOperand()} </li>
1234 *         </ul>
1235 *         </li>
1236 *         <li> expr1 -&gt;&gt; expr2
1237 *         <ul>
1238 *             <li>type: {@link EExpressionType#json_get_text}</li>
1239 *             <li>left operand:  {@link #getLeftOperand()}</li>
1240 *             <li>right operand: {@link #getLeftOperand()} </li>
1241 *         </ul>
1242 *         </li>
1243 *         <li> expr1 #&gt; expr2
1244 *         <ul>
1245 *             <li>type: {@link EExpressionType#json_get_object_at_path}</li>
1246 *             <li>left operand:  {@link #getLeftOperand()}</li>
1247 *             <li>right operand: {@link #getLeftOperand()} </li>
1248 *         </ul>
1249 *         </li>
1250 *         <li> expr1 #&gt;&gt; expr2
1251 *         <ul>
1252 *             <li>type: {@link EExpressionType#json_get_text_at_path}</li>
1253 *             <li>left operand:  {@link #getLeftOperand()}</li>
1254 *             <li>right operand: {@link #getLeftOperand()} </li>
1255 *         </ul>
1256 *         </li>
1257 *         <li> expr1 @&gt; expr2
1258 *         <ul>
1259 *             <li>type: {@link EExpressionType#json_left_contain}</li>
1260 *             <li>left operand:  {@link #getLeftOperand()}</li>
1261 *             <li>right operand: {@link #getLeftOperand()} </li>
1262 *         </ul>
1263 *         </li>
1264 *         <li> expr1 &gt;@ expr2
1265 *         <ul>
1266 *             <li>type: {@link EExpressionType#json_right_contain}</li>
1267 *             <li>left operand:  {@link #getLeftOperand()}</li>
1268 *             <li>right operand: {@link #getLeftOperand()} </li>
1269 *         </ul>
1270 *         </li>
1271 *         <li> expr1 ? expr2
1272 *         <ul>
1273 *             <li>type: {@link EExpressionType#json_exist}</li>
1274 *             <li>left operand:  {@link #getLeftOperand()}</li>
1275 *             <li>right operand: {@link #getLeftOperand()} </li>
1276 *         </ul>
1277 *         </li>
1278 *         <li> expr1 ?| expr2
1279 *         <ul>
1280 *             <li>type: {@link EExpressionType#json_any_exist}</li>
1281 *             <li>left operand:  {@link #getLeftOperand()}</li>
1282 *             <li>right operand: {@link #getLeftOperand()} </li>
1283 *         </ul>
1284 *         </li>
1285 *         <li> expr1 ?&amp; expr2</li>
1286 *             <li>type: {@link EExpressionType#json_all_exist}</li>
1287 *             <li>left operand:  {@link #getLeftOperand()}</li>
1288 *             <li>right operand: {@link #getLeftOperand()} </li>
1289 *
1290 *     </ul>
1291 *
1292 *      IS [NOT] A SET
1293 *     <ul>
1294 *         <li>Oracle set operator: IS [NOT] A SET
1295 *         <ul>
1296 *             <li>type: {@link EExpressionType#is_a_set_t}</li>
1297 *             <li>left operand:  {@link #getLeftOperand()}</li>
1298 *             <li>operator: N/A</li>
1299 *             </ul>
1300 *         </li>
1301 *         </ul>
1302 *
1303 *      Big Query ARRAY &lt;T&gt;[ expr_list ]
1304 *     <ul>
1305 *         <li>ARRAY &lt;T&gt;[ expr_list ], expr_list maybe empty
1306 *         <ul>
1307 *             <li>type: {@link EExpressionType#array_t}</li>
1308 *             <li>left operand:  {@link #getExprList()}</li>
1309 *             <li>{@link #getTypeName()} returns the T of this Array if specified.</li>
1310 *         </ul>
1311 *         </li>
1312 *      </ul>
1313 */
1314
1315public class TExpression extends TParseTreeNode{
1316
1317    private ArrayList<TObjectName> columnsInsideExpression = null;
1318
1319    public ArrayList<TObjectName> getColumnsInsideExpression(){
1320        if (columnsInsideExpression == null){
1321            columnsInsideExpression = new ArrayList<>();
1322        }
1323        if (!columnsInsideExpression.isEmpty()){
1324            return columnsInsideExpression;
1325        }
1326
1327        columnVisitor visitor = new columnVisitor(columnsInsideExpression);
1328        this.acceptChildren(visitor);
1329        return columnsInsideExpression;
1330    }
1331
1332    /**
1333     *  bigint(expr) in databricks, return EDataType.bigint_t
1334     *
1335     * @return datatype
1336     */
1337    public EDataType getCastDatatype() {
1338        return castDatatype;
1339    }
1340
1341    private EDataType castDatatype;
1342
1343//    public void setBigQueryExceptReplaceClause(TExceptReplaceClause node){
1344//        if (node == null) return;
1345//        this.fieldList = node.getColumnList();
1346//        //this.
1347//
1348//    }
1349
1350    public void setLeftUnary(TSourceToken st){
1351        switch (st.tokencode){
1352            case '+':
1353                this.expressionType = EExpressionType.unary_plus_t;
1354                break;
1355            case '-':
1356                this.expressionType = EExpressionType.unary_minus_t;
1357                break;
1358            case '@':
1359                this.expressionType = EExpressionType.unary_absolutevalue_t;
1360                break;
1361            case '~':
1362                this.expressionType = EExpressionType.unary_bitwise_not_t;
1363                break;
1364            default:
1365                break;
1366        }
1367    }
1368
1369    public void setRightUnary(TSourceToken st){
1370        switch (st.tokencode){
1371            case '!':
1372                this.expressionType = EExpressionType.unary_factorial_t;
1373                break;
1374            default:
1375                break;
1376        }
1377    }
1378
1379    private ArrayList<TDataConversion> dataConversions = null;
1380
1381    public void setDataConversions(ArrayList<TDataConversion> dataConversions) {
1382        this.dataConversions = dataConversions;
1383    }
1384
1385    public ArrayList<TDataConversion> getDataConversions() {
1386        if (this.dataConversions == null){
1387            this.dataConversions = new ArrayList<>();
1388        }
1389        return dataConversions;
1390    }
1391
1392    private String value;
1393
1394    public void setStringValue(String value) {
1395        this.value = value;
1396    }
1397
1398    public String getStringValue() {
1399        return value;
1400    }
1401
1402    private IType dataType = TPrimitiveType.Undefined;
1403
1404    public void setDataType(IType dataType) {
1405        this.dataType = dataType;
1406    }
1407
1408    public IType getDataType() {
1409        return dataType;
1410    }
1411
1412    private TCollectionArray collectionArray;
1413    private TCollectionCondition collectionCondition;
1414
1415    public TCollectionCondition getCollectionCondition() {
1416        return collectionCondition;
1417    }
1418
1419    public TCollectionArray getCollectionArray() {
1420        return collectionArray;
1421    }
1422
1423    private TNamedParameter namedParameter;
1424    private TPositionalParameter positionalParameter;
1425
1426    public TNamedParameter getNamedParameter() {
1427        return namedParameter;
1428    }
1429
1430    public TPositionalParameter getPositionalParameter() {
1431        return positionalParameter;
1432    }
1433
1434    private TObjectConstruct objectConstruct;
1435
1436    public TArrayConstruct getArrayConstruct() {
1437        return arrayConstruct;
1438    }
1439
1440    public TObjectConstruct getObjectConstruct() {
1441        return objectConstruct;
1442    }
1443
1444    private TArrayConstruct arrayConstruct;
1445
1446    private boolean onlyAndOrIsNonLeaf = false;
1447
1448
1449    public void  evaluate(Stack<TFrame> frameStack , TCustomSqlStatement sqlStatement){
1450        calculateExprVisitor cv = new calculateExprVisitor(frameStack, sqlStatement);
1451        this.postOrderTraverse(cv);
1452    }
1453    public Object evaluate(IEvaluationContext context){
1454        TExpressionEvaluator expressionEvaluator = new TExpressionEvaluator(context);
1455        this.postOrderTraverse(expressionEvaluator);
1456        return  this.getStringValue();
1457    }
1458
1459    /**
1460     * @deprecated As of v2.0.5.6, use class ColumnVisitor in package demos.columnInWhereClause instead.
1461     */
1462    public TExpressionList searchColumn(String columnName){
1463        TExpressionList resultList = new TExpressionList();
1464        this.inOrderTraverse(new searchColumnVisitor(columnName,resultList));
1465        return  resultList;
1466    }
1467
1468    private TFlattenVisitor flattenVisitor;
1469
1470    /**
1471     *
1472     * @return AND/OR token before expression when you get flattened expression using {@link #getFlattedAndOrExprs}
1473     */
1474    public TSourceToken getAndOrTokenBeforeExpr(){
1475        TSourceToken lcToken = getStartToken();
1476        if (lcToken == null)  return null;
1477        TSourceToken lcPrevToken = lcToken.prevSolidToken();
1478        if ((lcPrevToken.tokencode == TBaseType.rrw_and)||(lcPrevToken.tokencode == TBaseType.rrw_or)){
1479            return lcPrevToken;
1480        }else{
1481            return  null;
1482        }
1483    }
1484
1485    /**
1486     * Binary tree structure representation of expression makes AND/OR expression nested deeply
1487     * when there are lots of AND/OR condition is used.
1488     * Recursively function call on those nested AND/OR expression will cause stack overflow exception.
1489     * After flatten those expressions. we can iterate those expression in a linear way.
1490     * @return null if this is not AND/OR expression
1491     */
1492    public ArrayList getFlattedAndOrExprs(){
1493        if (!((expressionType == EExpressionType.logical_and_t)||(expressionType == EExpressionType.logical_or_t))){
1494            return  null;
1495        }
1496        if (flattenVisitor.getFlattedAndOrExprs().size() == 0){
1497            onlyAndOrIsNonLeaf = true;
1498            this.inOrderTraverse(flattenVisitor);
1499            onlyAndOrIsNonLeaf = false;
1500        }
1501        return flattenVisitor.getFlattedAndOrExprs();
1502    }
1503
1504//    private int flatAndOrExpr(){
1505//        int ret = 0;
1506//        if (!((expressionType == EExpressionType.logical_and_t)||(expressionType == EExpressionType.logical_or_t))){
1507//            return  0;
1508//        }
1509//        if (getFlattedAndOrExprs().size() > 0){
1510//            //already flatten, just return size
1511//            return  getFlattedAndOrExprs().size();
1512//        }
1513//
1514//        onlyAndOrIsNonLeaf = true;
1515//        this.inOrderTraverse(flattenVisitor);
1516//        onlyAndOrIsNonLeaf = false;
1517//        return  ret;
1518//    }
1519
1520    public void setTokenToIdentifier()
1521    {
1522        if (getExpressionType() == EExpressionType.simple_object_name_t){
1523            if (getObjectOperand().getEndToken() != null){
1524                getObjectOperand().getEndToken().tokencode = TBaseType.ident;
1525                getObjectOperand().getEndToken().tokentype = ETokenType.ttidentifier;
1526            }
1527        }else if (getExpressionType() == EExpressionType.simple_source_token_t){
1528            getSourcetokenOperand().tokencode = TBaseType.ident;
1529            getSourcetokenOperand().tokentype = ETokenType.ttidentifier;
1530        }
1531    }
1532
1533    public void setComparisonType(EComparisonType comparisonType) {
1534        this.comparisonType = comparisonType;
1535    }
1536
1537    static  public  EComparisonType getComparisonType(TSourceToken comparisonOperator){
1538        String tokenStr = comparisonOperator.getAstext();
1539        EComparisonType ret = EComparisonType.equals;
1540        switch (comparisonOperator.tokencode){
1541            case TBaseType.not_equal:
1542                if ((tokenStr.startsWith("!")) && (tokenStr.endsWith("=") )){
1543                    ret = EComparisonType.notEqualToExclamation;
1544                }else if ((tokenStr.startsWith("^")) && (tokenStr.endsWith("=") )){
1545                    ret = EComparisonType.notEqualToCaret;
1546                }else if ((tokenStr.startsWith("<")) && (tokenStr.endsWith(">") )){
1547                    if ((tokenStr.indexOf("=",1) > 0)&&((tokenStr.startsWith("<")) && (tokenStr.endsWith(">") ))) {
1548                        ret = EComparisonType.nullSafeEquals;
1549                    }else{
1550                        ret = EComparisonType.notEqualToBrackets;
1551                    }
1552                }
1553                break;
1554            case TBaseType.great_equal:
1555                ret = EComparisonType.greaterThanOrEqualTo;
1556                break;
1557            case TBaseType.less_equal:
1558                ret = EComparisonType.lessThanOrEqualTo;
1559                break;
1560            case TBaseType.not_great:
1561                ret = EComparisonType.notGreaterThan;
1562                if (tokenStr.startsWith("^")){
1563                    ret = EComparisonType.notGreaterThanToCaret;
1564                }
1565                break;
1566            case TBaseType.not_less:
1567                ret = EComparisonType.notLessThan;
1568                if (tokenStr.startsWith("^")){
1569                    ret = EComparisonType.notLessThanToCaret;
1570                }
1571
1572                break;
1573            case '=':
1574                ret = EComparisonType.equals;
1575                if ((tokenStr.indexOf("=",1) > 0)&&((tokenStr.startsWith("<")) && (tokenStr.endsWith(">") ))) {
1576                  ret = EComparisonType.nullSafeEquals;
1577                }
1578                break;
1579            case '>':
1580                ret = EComparisonType.greaterThan;
1581                break;
1582            case '<':
1583                ret = EComparisonType.lessThan;
1584                break;
1585            default:
1586                if (comparisonOperator.toString().equalsIgnoreCase("includes")){
1587                    ret = EComparisonType.includes;
1588                }else if (comparisonOperator.toString().equalsIgnoreCase("excludes")){
1589                    ret = EComparisonType.excludes;
1590                }else if (comparisonOperator.toString().equalsIgnoreCase("above")){
1591                    ret = EComparisonType.above;
1592                }else if (comparisonOperator.toString().equalsIgnoreCase("at")){
1593                    ret = EComparisonType.at;
1594                }else if (comparisonOperator.toString().equalsIgnoreCase("above_or_below")){
1595                    ret = EComparisonType.above_or_below;
1596                }else if (comparisonOperator.toString().equalsIgnoreCase("below")){
1597                    ret = EComparisonType.below;
1598                }
1599                break;
1600        }
1601        return ret;
1602    }
1603
1604    private TAliasClause exprAlias;
1605
1606    /**
1607     * In Teradata, it is possible there is an alias for expression
1608     * @return expression alias
1609     */
1610    public TAliasClause getExprAlias() {
1611        return exprAlias;
1612    }
1613
1614    public void setExprAlias(TAliasClause exprAlias) {
1615
1616        this.exprAlias = exprAlias;
1617    }
1618
1619    private TPTNodeList <TExplicitDataTypeConversion> dataTypeConversionList = null;
1620
1621    public void setDataTypeConversionList(TPTNodeList<TExplicitDataTypeConversion> dataTypeConversionList) {
1622        this.dataTypeConversionList = dataTypeConversionList;
1623    }
1624
1625    /**
1626     *
1627     * @deprecated since v2.5.3.1, replaced by {@link #getDataConversions()}
1628     */
1629    public TPTNodeList<TExplicitDataTypeConversion> getDataTypeConversionList() {
1630
1631        return dataTypeConversionList;
1632    }
1633
1634    private TExplicitDataTypeConversion dataTypeConversion;
1635
1636    public void setDataTypeConversion(TExplicitDataTypeConversion dataTypeConversion) {
1637        this.dataTypeConversion = dataTypeConversion;
1638    }
1639
1640    /**
1641     *
1642     * @return the first DataTypeConversion in {@link #getDataTypeConversionList}
1643     *
1644     * @deprecated since v2.5.3.1, replaced by {@link #getDataConversions()}
1645     */
1646    public TExplicitDataTypeConversion getDataTypeConversion() {
1647        if (dataTypeConversionList == null) return  null;
1648        return dataTypeConversionList.getElement(0);
1649    }
1650
1651    private TAnalyticFunction over_clause;
1652    private TObjectName sequenceName;
1653
1654    public TObjectName getSequenceName() {
1655        return sequenceName;
1656    }
1657
1658    public TAnalyticFunction getOver_clause() {
1659        return over_clause;
1660    }
1661
1662    public THiveVariable getHive_variable() {
1663        return hive_variable;
1664    }
1665
1666    private THiveVariable hive_variable = null;
1667
1668    public void setHive_variable(THiveVariable hive_variable) {
1669        this.hive_variable = hive_variable;
1670    }
1671
1672    private boolean isSymmetric = false;
1673
1674    public void setSymmetric(boolean symmetric) {
1675        isSymmetric = symmetric;
1676    }
1677
1678    /**
1679     * PostgreSQL
1680     *
1681     * BETWEEN SYMMETRIC is the same as BETWEEN except there is no requirement
1682     * that the argument to the left of AND be less than or equal to the argument
1683     * on the right. If it is not, those two arguments are automatically swapped,
1684     * so that a nonempty range is always implied.
1685     *
1686     * @return true if SYMMETRIC is used
1687     */
1688    public boolean isSymmetric() {
1689
1690        return isSymmetric;
1691    }
1692
1693    private TObjectAccess objectAccess = null;
1694
1695    public void setObjectAccess(TObjectAccess objectAccess) {
1696        this.objectAccess = objectAccess;
1697    }
1698
1699    public TObjectAccess getObjectAccess() {
1700
1701        return objectAccess;
1702    }
1703
1704    private TSourceToken operatorToken = null;
1705    private TSourceToken notToken = null;
1706    private boolean notOperator = false;
1707
1708    public boolean isNotOperator() {
1709        return notOperator;
1710    }
1711
1712    public void setNotToken(TSourceToken notToken) {
1713        this.notToken = notToken;
1714        notOperator = (this.notToken != null);
1715    }
1716
1717    public TSourceToken getNotToken() {
1718
1719        return notToken;
1720    }
1721
1722    private long plainTextLineNo = -1;
1723
1724    public void setPlainTextLineNo(long plainTextLineNo) {
1725        this.plainTextLineNo = plainTextLineNo;
1726    }
1727
1728    public void setPlainTextColumnNo(long plainTextColumnNo) {
1729        this.plainTextColumnNo = plainTextColumnNo;
1730    }
1731
1732    public long getPlainTextLineNo() {
1733        return plainTextLineNo;
1734    }
1735
1736    public long getPlainTextColumnNo() {
1737        return plainTextColumnNo;
1738    }
1739
1740    private  long plainTextColumnNo = -1;
1741
1742    public TExpression(){
1743
1744    }
1745
1746    public TExpression(TObjectName objectOperand){
1747        this.expressionType = EExpressionType.simple_object_name_t;
1748        this.objectOperand = objectOperand;
1749    }
1750
1751    public TExpression(TConstant constantOperand){
1752//        if ((constantOperand != null) && (constantOperand.getLiteralType() == ELiteralType.etFakeDate)){
1753//            this.expressionType = EExpressionType.function_t;
1754//            this.functionCall = new TFunctionCall();
1755//            this.functionCall.setFunctionType(EFunctionType.date_t);
1756//            this.functionCall.setFunctionName(new TObjectName(EDbObjectType.function, constantOperand.getStartToken()));
1757//            this.functionCall.setStartToken(constantOperand.getStartToken());
1758//            this.functionCall.setEndToken(constantOperand.getEndToken());
1759//
1760//        }else{
1761            this.expressionType = EExpressionType.simple_constant_t;
1762            this.constantOperand = constantOperand;
1763//        }
1764    }
1765
1766    public TExpression(TFunctionCall functionCall){
1767        this.expressionType = EExpressionType.function_t;
1768        this.functionCall = functionCall;
1769    }
1770
1771    public void setExecuteSqlNode(TExecuteSqlNode executeSqlNode) {
1772        this.executeSqlNode = executeSqlNode;
1773    }
1774
1775    public TExpression(EExpressionType pExpressionType){
1776        this.expressionType = pExpressionType;
1777    }
1778
1779    public TExpression(EExpressionType pExpressionType, TExpression pLeft, TExpression pRight){
1780        this(pExpressionType);
1781        this.leftOperand = pLeft;
1782        this.rightOperand = pRight;
1783    }
1784
1785    public TExpression(EExpressionType pExpressionType, TExpression pLeft, TExpression pRight, EComparisonType pComparisonType){
1786        this(pExpressionType,pLeft,pRight);
1787        this.comparisonType = pComparisonType;
1788    }
1789
1790    public static TExpression createExpression(EDbVendor dbVendor, TConstant constantOperand){
1791        TExpression expression = new TExpression(EExpressionType.simple_constant_t);
1792        expression.setConstantOperand(constantOperand);
1793        expression.dbvendor = dbVendor;
1794        return expression;
1795
1796    }
1797    public static TExpression createExpression(EDbVendor dbVendor, TObjectName objectOperand){
1798        TExpression expression = new TExpression(EExpressionType.simple_object_name_t);
1799        expression.setObjectOperand(objectOperand);
1800        expression.dbvendor = dbVendor;
1801        return expression;
1802    }
1803    public static TExpression createExpression(EDbVendor dbVendor,EExpressionType pExpressionType, TSourceToken pOperatorToken, TObjectName pLeft, TObjectName pRight){
1804        return TExpression.createExpression(dbVendor, pExpressionType, pOperatorToken
1805                , TExpression.createExpression(dbVendor, pLeft)
1806                , TExpression.createExpression(dbVendor, pRight)
1807        );
1808    }
1809
1810    public static TExpression createExpression(EDbVendor dbVendor,EExpressionType pExpressionType, TSourceToken pOperatorToken, TObjectName pLeft, TConstant pRight){
1811        return TExpression.createExpression(dbVendor, pExpressionType, pOperatorToken
1812                , TExpression.createExpression(dbVendor, pLeft)
1813                , TExpression.createExpression(dbVendor, pRight)
1814        );
1815    }
1816
1817    public static TExpression createExpression(EDbVendor dbVendor,EExpressionType pExpressionType, TSourceToken pOperatorToken, TExpression pLeft, TExpression pRight){
1818        TExpression expression = new TExpression(pExpressionType);
1819        expression.setOperatorToken(pOperatorToken);
1820        expression.setLeftOperand(pLeft);
1821        expression.setRightOperand(pRight);
1822        expression.dbvendor = dbVendor;
1823        return expression;
1824    }
1825
1826    public static TExpression createParenthesisExpression(TExpression pLeft){
1827        TExpression expression = new TExpression(EExpressionType.parenthesis_t);
1828        expression.setLeftOperand(pLeft);
1829        expression.dbvendor = pLeft.dbvendor;
1830        return expression;
1831    }
1832
1833    public void init(Object arg1){
1834        expressionType = (EExpressionType)arg1;
1835        if ((expressionType == EExpressionType.logical_and_t)||(expressionType == EExpressionType.logical_or_t)){
1836            flattenVisitor = new TFlattenVisitor();
1837        }
1838    }
1839    private TSourceToken leadingPrecision;
1840    private TSourceToken fractionalSecondsPrecision;
1841
1842    public void setLeadingPrecision(TSourceToken leadingPrecision) {
1843        this.leadingPrecision = leadingPrecision;
1844    }
1845
1846    public void setFractionalSecondsPrecision(TSourceToken fractionalSecondsPrecision) {
1847        this.fractionalSecondsPrecision = fractionalSecondsPrecision;
1848    }
1849
1850    public TSourceToken getLeadingPrecision() {
1851
1852        return leadingPrecision;
1853    }
1854
1855    public TSourceToken getFractionalSecondsPrecision() {
1856        return fractionalSecondsPrecision;
1857    }
1858
1859    public void init(Object arg1, Object arg2){
1860         init(arg1);
1861         switch (expressionType){
1862             case next_value_for_t:
1863                sequenceName = (TObjectName)arg2;
1864                break;
1865             case array_constructor_t:
1866                 if (arg2 instanceof TSelectSqlNode){
1867                     this.subQueryNode = (TSelectSqlNode)arg2;
1868                 }else if (arg2 instanceof TExpressionList){
1869                     this.exprList = (TExpressionList)arg2;
1870                 }else if (arg2 instanceof TArrayConstruct){
1871                     this.arrayConstruct = (TArrayConstruct)arg2;
1872                 }else if (arg2 instanceof TColumnDefinitionList){
1873                     this.colDefList = (TColumnDefinitionList) arg2;
1874                 }
1875                  break;
1876             case objectConstruct_t:
1877                 objectConstruct = (TObjectConstruct)arg2;
1878                 break;
1879             case namedParameter_t:
1880                 namedParameter = (TNamedParameter)arg2;
1881                 break;
1882             case positionalParameter_t:
1883                 positionalParameter = (TPositionalParameter)arg2;
1884                 break;
1885             case collectionArray_t:
1886                 collectionArray = (TCollectionArray)arg2;
1887                 break;
1888             case collectionCondition_t:
1889                 collectionCondition = (TCollectionCondition)arg2;
1890                 break;
1891             case year_to_month_t:
1892             case day_to_second_t:
1893             case at_local_t:
1894                 leftOperand = (TExpression)arg2;
1895                 break;
1896             case teradata_at_t:
1897                    leftOperand = (TExpression)arg1;
1898                    rightOperand = (TExpression)arg2;
1899                    break;
1900             case unnest_t:
1901                 leftOperand = (TExpression)arg2;
1902                 break;
1903             case list_t:
1904             case collection_constructor_list_t:
1905             case collection_constructor_multiset_t:
1906             case collection_constructor_set_t:
1907                 exprList = (TExpressionList)arg2;
1908                 break;
1909             case json_path_t:
1910                 this.json_path = (ArrayList<TIndices>)arg2;
1911                 break;
1912             case type_constructor_t:
1913                 objectOperand = (TObjectName) arg2;
1914                 break;
1915             case new_structured_type_t:
1916                 exprList = (TExpressionList)arg2;
1917                 markTeradataJsonFormatArguments();
1918                 break;
1919             default:
1920                 break;
1921         }
1922    }
1923
1924    public void init(Object arg1, Object arg2, Object arg3){
1925         init(arg1);
1926         switch (expressionType){
1927             case next_value_for_t:
1928                sequenceName = (TObjectName)arg2;
1929                 if (arg3 == null){
1930                 }else if (arg3 instanceof TExpression){
1931                     leftOperand = (TExpression)arg3;
1932                 }else if (arg3 instanceof TAnalyticFunction){
1933                    over_clause = (TAnalyticFunction)arg3;
1934                 }
1935                break;
1936             case assignment_t:
1937                 leftOperand = (TExpression)arg2;
1938                 rightOperand   = (TExpression)arg3;
1939                 break;
1940             case typecast_datatype_t:
1941                 //castDatatype = (EDataType)arg2;
1942                 typeName = (TTypeName)arg2;
1943                 leftOperand = (TExpression)arg3;
1944                 break;
1945             case json_access_t:
1946                 leftOperand = (TExpression)arg2;
1947                 rightOperand   = (TExpression)arg3;
1948                     break;
1949             case type_constructor_t:
1950                 objectOperand = (TObjectName) arg2;
1951                 exprList = (TExpressionList)arg3;
1952                 break;
1953             case cursor_attribute_t:
1954                 break;
1955             default:
1956                 leftOperand = (TExpression)arg2;
1957                 rightOperand   = (TExpression)arg3;
1958                 break;
1959         }
1960    }
1961
1962    /**
1963     * initialize a new instance of TExpression.
1964     *
1965     * @param arg1 type of this expression, a value of type {@link EExpressionType}
1966     * @param arg2 operator, a value of {@link TSourceToken}
1967     * @param arg3 left operand, a value of {@link TExpression}
1968     * the meaning of this parameter varies depends on the value of arg1.
1969     * @param arg4 right operand, a value of {@link TExpression}
1970     */
1971    public void init(Object arg1,Object arg2,Object arg3,Object arg4){
1972        init(arg1);
1973        operatorToken = (TSourceToken)arg2;
1974        switch (expressionType){
1975            case simple_object_name_t:
1976                objectOperand = (TObjectName)arg3;
1977                setStartToken(objectOperand);
1978                setEndToken(objectOperand);
1979                break;
1980            case simple_source_token_t:
1981                sourcetokenOperand = (TSourceToken)arg3;
1982                setStartToken(sourcetokenOperand);
1983                setEndToken(sourcetokenOperand);
1984                break;
1985            case simple_constant_t:
1986                constantOperand = (TConstant)arg3;
1987                setStartToken(constantOperand);
1988                setEndToken(constantOperand);
1989                break;
1990            case function_t:
1991                functionCall = (TFunctionCall)arg3;
1992                break;
1993//            case type_constructor_t:
1994//                functionCall = (TFunctionCall)arg3;
1995//                break;
1996            case arrayaccess_t:
1997                arrayAccess = (TArrayAccess)arg3;
1998                break;
1999            case array_access_expr_t:
2000                leftOperand = (TExpression)arg3;
2001                rightOperand   = (TExpression)arg4;
2002                break;
2003            case list_t:
2004            case collection_constructor_list_t:
2005            case collection_constructor_multiset_t:
2006            case collection_constructor_set_t:
2007                exprList = (TExpressionList)arg3;
2008                break;
2009            case field_doubt_t:
2010                TExpression l = (TExpression)arg3;
2011                if (l.getExpressionType() == EExpressionType.simple_object_name_t){
2012                    TObjectName objectName = l.getObjectOperand();
2013                    objectName.setSchemaToken(objectName.getObjectToken());
2014                    objectName.setObjectToken(objectName.getPartToken());
2015                    objectName.setPartToken((TSourceToken)arg4);
2016
2017                    expressionType = EExpressionType.simple_object_name_t;
2018                    this.objectOperand = l.getObjectOperand();
2019                }else {
2020                    expressionType = EExpressionType.field_t;
2021                }
2022                break;
2023            case column_definition_list_t:
2024                colDefList = (TColumnDefinitionList)arg3;
2025                break;
2026            case simple_comparison_t:
2027                leftOperand = (TExpression)arg3;
2028                leftOperand.setParentExpr(this);
2029                rightOperand = (TExpression)arg4;
2030                rightOperand.setParentExpr(this);
2031                comparisonOperator  = operatorToken;
2032                break;
2033            case implicit_datatype_cast_as_t:
2034                leftOperand = (TExpression)arg3;
2035                typeName = (TTypeName)arg4;
2036                break;
2037            default:
2038                if (arg3 != null){
2039                    leftOperand = (TExpression)arg3;
2040                    leftOperand.setParentExpr(this);
2041                }
2042                if (arg4 != null){
2043                    rightOperand = (TExpression)arg4;
2044                    rightOperand.setParentExpr(this);
2045                }
2046                break;
2047        }
2048    }
2049
2050    public void setOperatorToken(TSourceToken operatorToken) {
2051        this.operatorToken = operatorToken;
2052        switch (this.getExpressionType()){
2053            case unknown_t:
2054                switch (this.operatorToken.tokencode){
2055                    case TBaseType.OP_MINUS_GREAT:
2056                        this.expressionType =  EExpressionType.json_get_object;
2057                        break;
2058                    case TBaseType.OP_MINUS_GREAT_GREAT:
2059                        this.expressionType =  EExpressionType.json_get_text;
2060                        break;
2061                    case TBaseType.OP_POUND_GREAT_GREAT:
2062                        this.expressionType =  EExpressionType.json_get_text_at_path;
2063                        break;
2064                    case TBaseType.OP_POUND_GREAT:
2065                        this.expressionType =  EExpressionType.json_get_object_at_path;
2066                        break;
2067                    case TBaseType.OP_AT_GREAT:
2068                        this.expressionType =  EExpressionType.json_left_contain;
2069                        break;
2070                    case TBaseType.OP_LESS_AT:
2071                        this.expressionType =  EExpressionType.json_right_contain;
2072                        break;
2073                    case TBaseType.OP_JSONB_QUESTION: // ?
2074                        this.expressionType =  EExpressionType.json_exist;
2075                        break;
2076                    case TBaseType.OP_QUESTION_BAR:
2077                        this.expressionType =  EExpressionType.json_any_exist;
2078                        break;
2079                    case TBaseType.OP_QUESTION_PUNCTUATION:
2080                        this.expressionType =  EExpressionType.json_all_exist;
2081                        break;
2082                    case TBaseType.OP_TILDE_TILDE:
2083                        this.expressionType =  EExpressionType.pattern_matching_t;
2084                        break;
2085                    case TBaseType.OP_TILDE_TILDE_STAR:
2086                        this.expressionType =  EExpressionType.pattern_matching_t;
2087                        break;
2088                    case TBaseType.OP_EXCLAMATION_TIDLE_TIDLE:
2089                        this.expressionType =  EExpressionType.pattern_matching_t;
2090                        break;
2091                    case TBaseType.OP_EXCLAMATION_TIDLE_TIDLE_STAR:
2092                        this.expressionType =  EExpressionType.pattern_matching_t;
2093                        break;
2094                    case TBaseType.OP_TILDE_STAR:
2095                        this.expressionType =  EExpressionType.pattern_matching_t;
2096                        break;
2097                    case TBaseType.OP_EXCLAMATION_TILDE:
2098                        this.expressionType =  EExpressionType.pattern_matching_t;
2099                        this.setNotToken(operatorToken);
2100                        break;
2101                    case TBaseType.OP_EXCLAMATION_TIDLE_STAR:
2102                        this.expressionType =  EExpressionType.pattern_matching_t;
2103                        break;
2104                    case TBaseType.OP_TILDE_GREAT_TILDE:
2105                    case TBaseType.OP_TILDE_LESS_TILDE:
2106                    case TBaseType.OP_TILDE_GREAT_EQUAL_TILDE:
2107                    case TBaseType.OP_TILDE_LESS_EQUAL_TILDE:
2108                        this.expressionType =  EExpressionType.pattern_matching_t;
2109                        break;
2110                    case '~':
2111                        this.expressionType =  EExpressionType.pattern_matching_t;
2112                        break;
2113                    case TBaseType.OP_AT_MINUS_AT:
2114                    case TBaseType.OP_POUND_POUND:
2115                    case TBaseType.OP_PUNCTUATION_LESS:
2116                    case TBaseType.OP_PUNCTUATION_GREAT:
2117                    case TBaseType.OP_LESS_LESS_BAR:
2118                    case TBaseType.OP_BAR_GREAT_GREAT:
2119                    case TBaseType.OP_PUNCTUATION_LESS_BAR:
2120                    case TBaseType.OP_BAR_PUNCTUATION_GREAT:
2121                    case TBaseType.OP_LESS_CARET:
2122                    case TBaseType.OP_GREAT_CARET:
2123                    case TBaseType.OP_QUESTION_POUND:
2124                    case TBaseType.OP_QUESTION_MINUS:
2125                    case TBaseType.OP_QUESTION_MINUS_BAR:
2126                    case TBaseType.OP_QUESTION_BAR_BAR:
2127                    case TBaseType.OP_TILDE_EQUAL:
2128                    case TBaseType.OP_LESS_PERCENT:
2129                    case TBaseType.OP_GREAT_PERCENT:
2130                        this.expressionType =  EExpressionType.geo_t;
2131                        break;
2132                    case TBaseType.OP_LESS_LESS_EQUAL:
2133                    case TBaseType.OP_GREAT_GREAT_EQUAL:
2134                        this.expressionType =  EExpressionType.network_t;
2135                        break;
2136                    case TBaseType.OP_AT_AT_AT:
2137                    case TBaseType.OP_LESS_MINUS_GREAT:
2138                    case TBaseType.OP_LESS_HASH_GREAT:
2139                    case TBaseType.OP_LESS_EQUAL_GREAT:
2140                    case TBaseType.OP_LESS_PLUS_GREAT:
2141                    case TBaseType.OP_LESS_TILDE_GREAT:
2142                    case TBaseType.OP_LESS_PERCENT_GREAT:
2143                        this.expressionType =  EExpressionType.text_search_t;
2144                        break;
2145                    case TBaseType.OP_MINUS_BAR_MINUS:
2146                        this.expressionType = EExpressionType.range_t;
2147                        break;
2148                    case TBaseType.OP_PUNCTUATION_PUNCTUATION:
2149                        // '&&' — PostgreSQL-family overlaps operator
2150                        // (array/range/geometric), e.g. tags && ARRAY['a','b']
2151                        this.expressionType = EExpressionType.overlaps_t;
2152                        break;
2153                    case TBaseType.rrw_netezza_op_less_less:
2154                        this.expressionType = EExpressionType.left_shift_t;
2155                        break;
2156                    case TBaseType.rrw_netezza_op_great_great:
2157                        this.expressionType = EExpressionType.right_shift_t;
2158                        break;
2159                    case TBaseType.OP_POUND_MINUS:
2160                        this.expressionType = EExpressionType.json_delete_path;
2161                        break;
2162                    case TBaseType.OP_AT_QUESTION:
2163                        this.expressionType = EExpressionType.json_path_exists;
2164                        break;
2165                    case TBaseType.OP_AT_AT:
2166                        this.expressionType = EExpressionType.json_path_match;
2167                        break;
2168                    default:
2169                        break;
2170                }
2171
2172
2173                if (this.getExpressionType() == EExpressionType.unknown_t) {
2174                    if(this.operatorToken.toString().equalsIgnoreCase("%")){
2175                        this.expressionType =  EExpressionType.arithmetic_modulo_t;
2176                    }else if(this.operatorToken.toString().equalsIgnoreCase("&")){
2177                        this.expressionType = EExpressionType.bitwise_and_t;
2178                    }else if(this.operatorToken.toString().equalsIgnoreCase("|")){
2179                        this.expressionType = EExpressionType.bitwise_or_t;
2180                    }else if(this.operatorToken.toString().equalsIgnoreCase("#")){
2181                        this.expressionType = EExpressionType.bitwise_xor_t;
2182                    }else if(this.operatorToken.toString().equalsIgnoreCase("<<")){
2183                        this.expressionType = EExpressionType.left_shift_t;
2184                    }else if(this.operatorToken.toString().equalsIgnoreCase(">>")){
2185                        this.expressionType = EExpressionType.right_shift_t;
2186                    }else if(this.operatorToken.toString().equals("&&")){ // non-identifier-compare: operator token text
2187                        // vendors whose lexers emit '&&' as a generic operator
2188                        // token (e.g. Greenplum) rather than
2189                        // OP_PUNCTUATION_PUNCTUATION (Mantis 4608)
2190                        this.expressionType = EExpressionType.overlaps_t;
2191                    }
2192                }
2193
2194                break;
2195            case unary_left_unknown_t:
2196                if(this.operatorToken.toString().equalsIgnoreCase("|/")){
2197                    this.expressionType = EExpressionType.unary_squareroot_t;
2198                }else if(this.operatorToken.toString().equalsIgnoreCase("||/")){
2199                    this.expressionType = EExpressionType.unary_cuberoot_t;
2200                }else if(this.operatorToken.toString().equalsIgnoreCase("!!")){
2201                    this.expressionType = EExpressionType.unary_factorialprefix_t;
2202                }else if(this.operatorToken.toString().equalsIgnoreCase("@")){
2203                    this.expressionType = EExpressionType.unary_absolutevalue_t;
2204                }else if(this.operatorToken.toString().equalsIgnoreCase("~")){
2205                    this.expressionType = EExpressionType.unary_bitwise_not_t;
2206                }else if(this.operatorToken.toString().equalsIgnoreCase("-")){
2207                    this.expressionType = EExpressionType.unary_minus_t;
2208                }else if(this.operatorToken.toString().equalsIgnoreCase("+")){
2209                    this.expressionType = EExpressionType.unary_plus_t;
2210                }
2211
2212                break;
2213            case unary_right_unknown_t:
2214                if(this.operatorToken.toString().equalsIgnoreCase("!")) {
2215                    this.expressionType = EExpressionType.unary_factorial_t;
2216                }
2217                break;
2218            default:
2219                break;
2220        }
2221
2222    }
2223
2224
2225    private ArrayList<TSourceToken> operatorTokens = null;
2226
2227    /**
2228     * Operator token used in expression which contains multiple operator tokens such as SIMILAR TO , IS DISTINCT FROM and etc
2229     * added since v3.0.8.6
2230     *
2231     * @return operator token list
2232     */
2233    public ArrayList<TSourceToken> getOperatorTokens() {
2234        if (operatorTokens == null){
2235            operatorTokens = new ArrayList<>();
2236        }
2237        return operatorTokens;
2238    }
2239
2240    /**
2241     * Operator token used in expression such as +,-,*,/ and etc
2242     * @return operator token
2243     */
2244    public TSourceToken getOperatorToken() {
2245
2246        return operatorToken;
2247    }
2248
2249    public void setVal(Object val) {
2250        this.val = val;
2251    }
2252
2253    private boolean valPartial = false;
2254
2255    /**
2256     * True when {@link #getVal()} holds a string value that contains
2257     * placeholder identifiers for unknowable parts (unresolved variables,
2258     * function calls), e.g. a concatenation where only some operands are
2259     * string literals. Partially resolved dynamic SQL is still analyzed for
2260     * approximate lineage, but parse failures must not be reported as syntax
2261     * errors because the text was never the real SQL.
2262     */
2263    public boolean isValPartial() {
2264        return valPartial;
2265    }
2266
2267    public void setValPartial(boolean valPartial) {
2268        this.valPartial = valPartial;
2269    }
2270
2271    /**
2272     * value of this expression, valid only after evaluate this expression.
2273     * @return a value object
2274     */
2275    public Object getVal() {
2276
2277        return val;
2278    }
2279
2280    private Object val = null;
2281
2282    // expression type value
2283
2284    // simple expression
2285
2286
2287    public TConstant getConstantOperand() {
2288        return constantOperand;
2289    }
2290
2291
2292    public void setNewVariantTypeArgumentList(TNewVariantTypeArgumentList newVariantTypeArgumentList) {
2293        this.newVariantTypeArgumentList = newVariantTypeArgumentList;
2294    }
2295
2296    public TNewVariantTypeArgumentList getNewVariantTypeArgumentList() {
2297        return newVariantTypeArgumentList;
2298    }
2299
2300    private TNewVariantTypeArgumentList newVariantTypeArgumentList = null;
2301
2302    /**
2303     * PLSQL:
2304     * <p> expr typecast typename
2305     * <p>
2306     * <p> Postgresql
2307     * <p> expr::typename
2308     * <p>
2309     * <p> Informix
2310     * <p> expr::typename
2311     * <p>
2312     * <p> expr can be accessed via {@link #leftOperand}, typename can be accessed via {@link #getTypeName()}
2313     */
2314
2315    private  TTypeName typeName;
2316
2317    public void setTypeName(TTypeName typeName) {
2318        this.typeName = typeName;
2319    }
2320
2321    public TTypeName getTypeName() {
2322
2323        return typeName;
2324    }
2325
2326    /**
2327     * valid when {@link #getExpressionType() } is {@link TExpression#fieldSelection}
2328     * @return field name
2329     */
2330    public TObjectName getFieldName() {
2331        return fieldName;
2332    }
2333
2334    private  TObjectName fieldName;
2335
2336    public void setIndirection(TIndirection indirection) {
2337        if (indirection != null){
2338            if (indirection.isRealIndices()){
2339                this.subscripts = true;
2340            }else{
2341                //this.setExpressionType(TExpression.fieldSelection);
2342                setExpressionType(EExpressionType.fieldselection_t);
2343                this.fieldName = indirection.getIndices().getElement(0).getAttributeName();
2344                //this.fieldName.setObjectType(TObjectName.ttobjFieldName);
2345                this.fieldName.setDbObjectType(EDbObjectType.fieldName);
2346            }
2347            this.indirection = indirection;
2348        }
2349    }
2350
2351    private  boolean  subscripts;
2352
2353    /**
2354     * If an expression yields a value of an array type, then a specific element of the array value can be extracted by writing
2355     * <p> expression[subscript]
2356     * <p> or multiple adjacent elements (an "array slice") can be extracted by writing
2357     * <p> expression[lower_subscript:upper_subscript]
2358     * <p> In general the array expression must be parenthesized, but the parentheses can be omitted when the expression to be subscripted is just a column reference or positional parameter.
2359     * <p> Also, multiple subscripts can be concatenated when the original array is multidimensional. For example:
2360     * <p>
2361     * <p> when sytnax like this:
2362     * <p> mytable.arraycolumn[4]
2363     * <p> mytable.two_d_column[17][34]
2364     * <p> $1[10:42]
2365     * <p>
2366     * <p> check {@link #getObjectOperand()} for more detailed information about subscript.
2367     * <p>
2368     * <p> when syntax like this:
2369     * <p> (arrayfunction(a,b))[42]
2370     * <p>
2371     * <p> check {@link #getIndirection()} when {@link #isSubscripts()} is true.
2372     * @return tells whether it is an expression with subscript.
2373     */
2374    public boolean isSubscripts() {
2375        return subscripts;
2376    }
2377
2378    public ArrayList<TIndices> getJson_path() {
2379        return json_path;
2380    }
2381
2382    private ArrayList<TIndices> json_path;
2383
2384    /**
2385     * The expressions inside the subscripts that follow this expression, {@code split(s, ':')[n]} in Presto and
2386     * Trino: column references that TSQLResolver2 and the lineage analyzer read like any other (Mantis 4817).
2387     * Empty without a subscript.
2388     *
2389     * @return the subscript expressions, never null
2390     */
2391    public java.util.List<TExpression> getSubscriptExpressions() {
2392        if (indirection == null) return java.util.Collections.<TExpression>emptyList();
2393        return indirection.getSubscriptExpressions();
2394    }
2395
2396    public TIndirection getIndirection() {
2397        return indirection;
2398    }
2399
2400    private TIndirection indirection;
2401
2402    private boolean notModifier;
2403
2404    /**
2405     * return true for expression like this: <expr> NOT IS NULL, <expr> NOT LIKE <expr> , <expr> NOT BETWEEN <expr> AND <expr>
2406     * and return false for expression like this: <expr> IS NULL, <expr> LIKE <expr> , <expr> BETWEEN <expr> AND <expr>
2407     * @return
2408     */
2409
2410    /**
2411     * @deprecated As of v1.4.3.0, replaced by {@link #getNotToken()}
2412     */
2413    public boolean isNotModifier() {
2414        notModifier = (getOperatorToken() != null);
2415        if (notModifier){
2416            notModifier = (getOperatorToken().tokencode == TBaseType.rrw_not);
2417        }
2418        return notModifier;
2419    }
2420
2421    private  TOutputFormatPhraseList outputFormatPhraseList;
2422
2423    public void setOutputFormatPhraseList(TOutputFormatPhraseList outputFormatPhraseList) {
2424        this.outputFormatPhraseList = outputFormatPhraseList;
2425    }
2426
2427    /**
2428     * teradata:
2429     * <p>column_expr (named alias_name)
2430     * @return (named alias_name) in column_expr
2431     */
2432    public TOutputFormatPhraseList getOutputFormatPhraseList() {
2433
2434        return outputFormatPhraseList;
2435    }
2436
2437    public TExpressionList getExprList() {
2438        return exprList;
2439    }
2440
2441    /**
2442     * Teradata {@code NEW JSON('...', LATIN)}: an argument after the value names its character set or binary format
2443     * (LATIN, UNICODE, BSON, UBJSON), never a column, so neither column linking nor lineage may read it as one
2444     * (Mantis 4919). Marked when the node is built, because a method call on the constructed value,
2445     * {@code (NEW JSON(...)).JSONEXTRACTVALUE(...)}, is never parsed further.
2446     */
2447    private void markTeradataJsonFormatArguments(){
2448        if ((dbvendor != EDbVendor.dbvteradata) || (exprList == null) || (exprList.size() == 0)) return;
2449        TExpression constructor = exprList.getExpression(0);
2450        if ((constructor == null) || (constructor.getExpressionType() != EExpressionType.function_t)
2451                || (constructor.getFunctionCall() == null) || (constructor.getFunctionCall().getArgs() == null)) return;
2452        TObjectName typeName = constructor.getFunctionCall().getFunctionName();
2453        if ((typeName == null) || !typeName.toString().equalsIgnoreCase("JSON")) return; // non-identifier-compare: built-in type keyword JSON
2454        TExpressionList args = constructor.getFunctionCall().getArgs();
2455        for (int i = 1; i < args.size(); i++){
2456            TExpression arg = args.getExpression(i);
2457            if ((arg == null) || (arg.getExpressionType() != EExpressionType.simple_object_name_t)
2458                    || (arg.getObjectOperand() == null)) continue;
2459            TObjectName format = arg.getObjectOperand();
2460            String word = format.toString();
2461            if (word.equalsIgnoreCase("LATIN") || word.equalsIgnoreCase("UNICODE") || word.equalsIgnoreCase("BSON") || word.equalsIgnoreCase("UBJSON")){ // non-identifier-compare: Teradata JSON format keywords
2462                format.setObjectType(TObjectName.ttobjNotAObject);
2463                format.setValidate_column_status(TBaseType.VALIDATED_CAN_NOT_BE_A_COLUMN_NAME);
2464                format.setDbObjectTypeDirectly(EDbObjectType.notAColumn);
2465            }
2466        }
2467    }
2468
2469    private TIntervalExpression intervalExpr = null;
2470
2471    public void setIntervalExpr(TIntervalExpression intervalExpr) {
2472        this.intervalExpr = intervalExpr;
2473    }
2474
2475    public TIntervalExpression getIntervalExpr() {
2476
2477        return intervalExpr;
2478    }
2479
2480    private TExpressionList exprList = null;
2481
2482    private TExceptReplaceClause exceptReplaceClause;
2483
2484    public TExceptReplaceClause getExceptReplaceClause() {
2485        if (exceptReplaceClause == null) {
2486            if (this.getObjectOperand()!=null) {
2487                if (this.getObjectOperand().getExceptReplaceClause()!=null) {
2488                    exceptReplaceClause = this.getObjectOperand().getExceptReplaceClause();
2489                }else if (this.getIndirection()!=null) {
2490                    if (this.getIndirection().getIndices()!=null) {
2491                        if (this.getIndirection().getIndices().size()>0) {
2492                            exceptReplaceClause = this.getIndirection().getIndices().getElement(0).getAttributeName().getExceptReplaceClause();
2493                        }
2494                    }
2495                }
2496            }
2497        }
2498        return exceptReplaceClause;
2499    }
2500
2501    public void setExceptReplaceClause(TExceptReplaceClause exceptReplaceClause) {
2502        this.exceptReplaceClause = exceptReplaceClause;
2503    }
2504
2505    private TObjectNameList fieldList;
2506
2507    public void setFieldList(TObjectNameList fieldList) {
2508        this.fieldList = fieldList;
2509    }
2510
2511    public TObjectNameList getFieldList() {
2512
2513        return fieldList;
2514    }
2515
2516    private TInExpr inExpr = null;
2517
2518    public void setInExpr(TInExpr inExpr) {
2519        this.inExpr = inExpr;
2520    }
2521
2522    /**
2523     * @deprecated As of v1.4.3.3, replaced by {@link #getRightOperand()}
2524     */
2525    public TInExpr getInExpr() {
2526        return inExpr;
2527    }
2528
2529
2530    public void setExprList(TExpressionList exprList) {
2531        this.exprList = exprList;
2532    }
2533
2534    public void setOracleOuterJoin(boolean oracleOuterJoin) {
2535        isOracleOuterJoin = oracleOuterJoin;
2536    }
2537
2538    public boolean isOracleOuterJoin() {
2539        return isOracleOuterJoin;
2540    }
2541
2542    /**
2543     *  Proprietary jion syntax of oracle: column(+)
2544     */
2545    private boolean isOracleOuterJoin = false;
2546
2547    /**
2548     * ClickHouse GLOBAL IN / GLOBAL NOT IN modifier.
2549     * When true, indicates the IN operator uses the GLOBAL keyword for distributed query execution.
2550     */
2551    private boolean globalIn = false;
2552
2553    public boolean isGlobalIn() {
2554        return globalIn;
2555    }
2556
2557    public void setGlobalIn(boolean globalIn) {
2558        this.globalIn = globalIn;
2559    }
2560
2561    private TExpression parentExpr;
2562
2563    public TExpression getParentExpr() {
2564        return parentExpr;
2565    }
2566
2567    public void setParentExpr(TExpression parentExpr) {
2568        this.parentExpr = parentExpr;
2569    }
2570
2571    public boolean isLeftOperandOfParent(){
2572        if (this.getParentExpr() == null) return false;
2573        return  (this == this.getParentExpr().getLeftOperand());
2574    }
2575
2576    public boolean isRightOperandOfParent(){
2577        if (this.getParentExpr() == null) return false;
2578        return  (this == this.getParentExpr().getRightOperand());
2579    }
2580
2581    public void setLeftOperand(TExpression leftOperand) {
2582        this.leftOperand = leftOperand;
2583        if (leftOperand != null){
2584            leftOperand.setParentExpr(this);
2585        }
2586
2587//        if (leftOperand == null){
2588//            TParseTreeNode.removeTokensBetweenNodes(this.leftOperand,this.rightOperand);
2589//        }
2590//
2591//        this.setNewSubNode(this.leftOperand,leftOperand,null);
2592//        this.leftOperand = leftOperand;
2593//        if (this.getNodeStatus() == ENodeStatus.nsRemoved){
2594//            // remove this expr cascade due to the left operand was removed
2595//            if (this.getParentExpr() != null){
2596//                if (this == this.getParentExpr().getLeftOperand()){
2597//                    if ((this.getParentExpr().getRightOperand() != null)&&(this.getParentExpr().getRightOperand().getNodeStatus() != ENodeStatus.nsRemoved)){
2598//                        this.getParentExpr().refreshAllNodesTokenCount();
2599//                        this.getParentExpr().removeTokensBetweenToken(this.getParentExpr().getStartToken(),this.getParentExpr().getRightOperand().getStartToken().getPrevTokenInChain());
2600//                        this.getParentExpr().updateNodeWithTheSameStartToken(TParseTreeNode.nodeChangeStartToken ,this.getParentExpr().getRightOperand().getStartToken());
2601//                    }
2602//                }else{
2603//                    if ((this.getParentExpr().getLeftOperand() != null)&&(this.getParentExpr().getLeftOperand().getNodeStatus() != ENodeStatus.nsRemoved)){
2604//                        this.getParentExpr().refreshAllNodesTokenCount();
2605//                        this.getParentExpr().removeTokensBetweenToken(this.getParentExpr().getLeftOperand().getEndToken().getNextTokenInChain(),this.getParentExpr().getEndToken());
2606//                        this.getParentExpr().updateMeNodeWithTheSameEndToken(TParseTreeNode.nodeChangeEndToken ,this.getParentExpr().getLeftOperand().getEndToken());
2607//                    }
2608//                }
2609//            }
2610//            this.setStartTokenDirectly(null);
2611//            this.setEndTokenDirectly(null);
2612//        }
2613//
2614    }
2615
2616    public void setRightOperand(TExpression rightOperand) {
2617
2618        this.rightOperand = rightOperand;
2619        if (rightOperand != null){
2620            rightOperand.setParentExpr(this);
2621        }
2622
2623//        if (rightOperand == null){
2624//            TParseTreeNode.removeTokensBetweenNodes(this.leftOperand,this.rightOperand);
2625//        }
2626//
2627//        this.setNewSubNode(this.rightOperand,rightOperand,null);
2628//        this.rightOperand = rightOperand;
2629//
2630//        if (this.getNodeStatus() == ENodeStatus.nsRemoved){
2631//            // remove this expr cascade due to the left operand was removed
2632//            if (this.getParentExpr() != null){
2633//                if (this == this.getParentExpr().getLeftOperand()){
2634//                    if ((this.getParentExpr().getRightOperand() != null)&&(this.getParentExpr().getRightOperand().getNodeStatus() != ENodeStatus.nsRemoved)){
2635//                        this.getParentExpr().refreshAllNodesTokenCount();
2636//                        this.getParentExpr().removeTokensBetweenToken(this.getParentExpr().getStartToken(),this.getParentExpr().getRightOperand().getStartToken().getPrevTokenInChain());
2637//                        this.getParentExpr().updateNodeWithTheSameStartToken(TParseTreeNode.nodeChangeStartToken ,this.getParentExpr().getRightOperand().getStartToken());
2638//                    }
2639//                }else{
2640//                    if ((this.getParentExpr().getLeftOperand() != null)&&(this.getParentExpr().getLeftOperand().getNodeStatus() != ENodeStatus.nsRemoved)){
2641//                        this.getParentExpr().refreshAllNodesTokenCount();
2642//                        this.getParentExpr().removeTokensBetweenToken(this.getParentExpr().getLeftOperand().getEndToken().getNextTokenInChain(),this.getParentExpr().getEndToken());
2643//                        this.getParentExpr().updateMeNodeWithTheSameEndToken(TParseTreeNode.nodeChangeEndToken ,this.getParentExpr().getLeftOperand().getEndToken());
2644//                    }
2645//                }
2646//            }
2647//            this.setStartTokenDirectly(null);
2648//            this.setEndTokenDirectly(null);
2649//        }
2650//
2651//        if (rightOperand != null){
2652//            rightOperand.setParentExpr(this);
2653//        }
2654    }
2655
2656    private TExpression leftOperand;
2657    private TExpression rightOperand;
2658
2659    private TArrayAccess arrayAccess = null;
2660
2661
2662    /*
2663     *
2664     * @return if leftOperand is not null, then return leftOperand,
2665     * otherwise, check other possible parse tree node that might be in left side of this expression.
2666     * <p>This function was called in preOrderTraverse, inOrderTraverse and postOrderTraverse
2667     * <p>This function is only valid when {@link gudusoft.gsqlparser.nodes.TExpression#isLeaf()} is not true.
2668     *
2669     * <p>take this expression for example:
2670     * <p>f in (1,2,3)
2671     * <p> rightOperand is null, but getRightNode() should return (1,2,3) which is {@link TExpression#exprList}
2672     *
2673    public TParseTreeNode getLeftNode() {
2674        TParseTreeNode ret = this.leftOperand;
2675        if ( ret == null) {
2676            ret = this.leftNode;
2677        }
2678        return ret;
2679    }
2680     */
2681
2682    /*
2683     *
2684     * @return if rightOperand is not null, then return rightOperand,
2685     * otherwise, check other possible parse tree node that might be in right side of this expression.
2686     * <p>This function was called in preOrderTraverse, inOrderTraverse and postOrderTraverse
2687     * <p>This function is only valid when {@link gudusoft.gsqlparser.nodes.TExpression#isLeaf()} is not true.
2688
2689     * <p>take this expression for example:
2690     * <p>f in (1,2,3)
2691     * <p> rightOperand is null, but getRightNode() should return (1,2,3) which is {@link TExpression#exprList}
2692    public TParseTreeNode getRightNode(){
2693        TParseTreeNode ret = this.rightOperand;
2694        if ( ret == null) {
2695            ret = this.rightNode;
2696        }
2697        return ret;
2698    }
2699     */
2700
2701    /**
2702     *
2703     * @return right operand of this expression which should be type of TExpression
2704     */
2705    public TExpression getRightOperand() {
2706        return rightOperand;
2707    }
2708
2709    /**
2710     *
2711     * @return left operand of this expression which should be type of TExpression
2712     */
2713    public TExpression getLeftOperand() {
2714
2715        return leftOperand;
2716    }
2717
2718    public TExpression getLikeEscapeOperand() {
2719        return likeEscapeOperand;
2720    }
2721
2722    public TExpression getBetweenOperand() {
2723        return betweenOperand;
2724    }
2725
2726    public TArrayAccess getArrayAccess() {
2727        return arrayAccess;
2728    }
2729
2730    private EExpressionType expressionType = EExpressionType.not_initialized_yet_t;
2731
2732    /**
2733     * change return type from int to EExpressionType since 1.4.3.0
2734     * @return a value of {@link EExpressionType}
2735     */
2736    public EExpressionType getExpressionType() {
2737        return expressionType;
2738    }
2739
2740    /**
2741     *
2742     * @param exprType type to distinguish expression, change type from int to
2743     * EExpressionType since 1.4.3.0
2744     */
2745    public void setExpressionType(EExpressionType exprType) {
2746        this.expressionType = exprType;
2747    }
2748
2749    //private int expressionType = unknown;
2750
2751    public void setObjectOperand(TObjectName objectOperand) {
2752        this.objectOperand = objectOperand;
2753    }
2754
2755    public TObjectName getObjectOperand() {
2756        return objectOperand;
2757    }
2758
2759    private TObjectName objectOperand;
2760
2761    public void setConstantOperand(TConstant constantOperand) {
2762        this.constantOperand = constantOperand;
2763    }
2764
2765    private TConstant constantOperand;
2766
2767    public TSourceToken getSourcetokenOperand() {
2768        return sourcetokenOperand;
2769    }
2770
2771    public void setSourcetokenOperand(TSourceToken sourcetokenOperand) {
2772        this.sourcetokenOperand = sourcetokenOperand;
2773    }
2774
2775    private TSourceToken sourcetokenOperand;
2776
2777    public void setCaseExpression(TCaseExpression caseExpression) {
2778        this.caseExpression = caseExpression;
2779    }
2780
2781    public TCaseExpression getCaseExpression() {
2782        return caseExpression;
2783    }
2784
2785    private TCaseExpression caseExpression;
2786
2787    /**
2788     * @deprecated As of v1.4.3.3
2789     */
2790    public void setArrayAccess(TArrayAccess arrayAccess) {
2791        this.arrayAccess = arrayAccess;
2792    }
2793
2794    private TExecuteSqlNode executeSqlNode;
2795
2796    public TExecuteSqlNode getExecuteSqlNode() {
2797        return executeSqlNode;
2798    }
2799
2800    private TCallSqlNode callSqlNode;
2801
2802    public TCallSqlNode getCallSqlNode() {
2803        return callSqlNode;
2804    }
2805
2806    public void setCallSqlNode(TCallSqlNode callSqlNode) {
2807        this.callSqlNode = callSqlNode;
2808    }
2809
2810    public void setSubQueryNode(TSelectSqlNode subQueryNode) {
2811        this.subQueryNode = subQueryNode;
2812    }
2813
2814    private TSelectSqlNode subQueryNode = null;
2815
2816    public void setSubQuery(TSelectSqlStatement subQuery) {
2817        this.subQuery = subQuery;
2818    }
2819
2820    public TSelectSqlStatement getSubQuery() {
2821        return subQuery;
2822    }
2823
2824    private TSelectSqlStatement subQuery = null;
2825
2826    public void setSubQueryInStmt(boolean subQueryInStmt) {
2827        isSubQueryInStmt = subQueryInStmt;
2828    }
2829
2830    private boolean isSubQueryInStmt = false;   // plsql, subQuery already was set to TSelectSqlStatement, but not parsed
2831
2832    private TFunctionCall functionCall;
2833
2834    public TFunctionCall getFunctionCall() {
2835        return functionCall;
2836    }
2837
2838    public void setFunctionCall(TFunctionCall functionCall) {
2839        this.functionCall = functionCall;
2840    }
2841
2842    private TDatetimeExpression datetimeExpression;
2843
2844    public void setDatetimeExpression(TDatetimeExpression datetimeExpression) {
2845        this.datetimeExpression = datetimeExpression;
2846    }
2847
2848    private TIntervalExpression intervalExpression;
2849
2850    public void setIntervalExpression(TIntervalExpression intervalExpression) {
2851        this.intervalExpression = intervalExpression;
2852    }
2853
2854    private TExpression betweenOperand;
2855
2856    public void setBetweenOperand(TExpression betweenOperand) {
2857        this.betweenOperand = betweenOperand;
2858    }
2859
2860    private TExpression likeEscapeOperand;
2861
2862    public void setLikeEscapeOperand(TExpression likeEscapeOperand) {
2863        this.likeEscapeOperand = likeEscapeOperand;
2864    }
2865
2866
2867    public void doParse(TCustomSqlStatement psql, ESqlClause plocation){
2868
2869        setLocation(plocation);
2870
2871        switch(expressionType){
2872            case simple_constant_t:
2873                if (this.constantOperand.getStartToken() != null){
2874                    this.constantOperand.getStartToken().location = plocation;
2875                }
2876                // INTERVAL t.n DAY (BigQuery, MySQL): the value of the interval is an expression whose columns and
2877                // subqueries are parsed like any other operand (Mantis 4918)
2878                if (this.constantOperand.getInt64_expression() != null){
2879                    this.constantOperand.getInt64_expression().doParse(psql,plocation);
2880                }
2881                break;
2882            case simple_object_name_t:
2883                // target_el_expr -> basic3_expr -> simple_expression
2884                psql.linkColumnReferenceToTable(objectOperand,plocation);
2885                psql.linkColumnToTable(objectOperand,plocation);
2886
2887//                if (plocation == ESqlClause.selectInto){
2888//                    if (this.objectOperand.toString().startsWith("#")){
2889//                        TTable table = new TTable();
2890//                        this.objectOperand.setObjectType(TObjectName.ttobjTable);
2891//                        table.setTableName(this.objectOperand);
2892//                        table.setTableType(ETableSource.objectname);
2893//                        table.setEffectType(ETableEffectType.tetSelectInto);
2894//                        psql.addToTables(table);
2895//                    }else{
2896//                        this.objectOperand.setObjectType(TObjectName.ttobjVariable);
2897//                    }
2898//                }else{
2899//                    psql.linkColumnReferenceToTable(objectOperand,plocation);
2900//                    psql.linkColumnToTable(objectOperand,plocation);
2901//                }
2902                break;
2903            case group_t:
2904                inExpr.doParse(psql,plocation);
2905                break;
2906            case list_t:
2907            case collection_constructor_list_t:
2908            case collection_constructor_multiset_t:
2909            case collection_constructor_set_t:
2910            case new_structured_type_t:
2911                if (exprList != null){
2912                    exprList.doParse(psql,plocation);
2913                }
2914                break;
2915            case function_t:
2916                if (functionCall.getArgs() != null){
2917                    for(int i=0;i<functionCall.getArgs().size();i++){
2918                        functionCall.getArgs().getExpression(i).setParentExpr(this);
2919                    }
2920                }
2921                functionCall.doParse(psql,plocation);
2922                break;
2923            case object_access_t:
2924                // (t.j).JSONEXTRACTVALUE('$.a'), XMLTYPE(c).getStringVal(): the object that a method or an attribute
2925                // is read from is an operand of the clause, linked like any other (Mantis 4919)
2926                if ((objectAccess != null) && (objectAccess.getObjectExpr() != null)){
2927                    objectAccess.getObjectExpr().doParse(psql,plocation);
2928                }
2929                break;
2930
2931            case type_constructor_t:
2932                if (getExprList() != null){
2933                    getExprList().doParse(psql,plocation);
2934                }
2935
2936                break;
2937            case cursor_t:
2938            case subquery_t:
2939            case multiset_t:
2940                if (subQuery == null){
2941                    subQuery = new TSelectSqlStatement(psql.dbvendor);
2942                    subQuery.rootNode = subQueryNode;
2943                }
2944                subQuery.setLocation(plocation);
2945
2946                if (!isSubQueryInStmt){
2947                    subQuery.doParseStatement(psql);
2948                }else{
2949                    // subQuery in plsql
2950                 subQuery.parsestatement(psql,false);
2951                }
2952                break;
2953            case case_t:
2954                caseExpression.doParse(psql,plocation);
2955                break;
2956            case pattern_matching_t:
2957                // leftOperand may be null for dangling predicates in CASE expressions
2958                if (leftOperand != null) {
2959                    leftOperand.doParse(psql,plocation);
2960                }
2961                rightOperand.doParse(psql,plocation);
2962                if (likeEscapeOperand != null){
2963                    likeEscapeOperand.doParse(psql,plocation);
2964                }
2965                break;
2966            case exists_t:
2967                if (subQueryNode != null){
2968                    if (subQuery == null){
2969                        subQuery = new TSelectSqlStatement(psql.dbvendor);
2970                        subQuery.rootNode = subQueryNode;
2971                    }
2972                    if (!isSubQueryInStmt){
2973                        subQuery.doParseStatement(psql);
2974                    }else{
2975                        // subQuery in plsql
2976                        subQuery.parsestatement(psql,false);
2977                    }
2978                }else if (this.leftOperand != null){
2979                    // databricks, exists(expr, func)
2980                }
2981                break;
2982            case new_variant_type_t:
2983                this.newVariantTypeArgumentList.doParse(psql,plocation);
2984                break;
2985            case unary_plus_t:
2986            case unary_minus_t:
2987            case unary_prior_t:
2988                rightOperand.doParse(psql,plocation);
2989                break;
2990            case arithmetic_plus_t:
2991            case arithmetic_minus_t:
2992            case arithmetic_times_t:
2993            case arithmetic_divide_t:
2994            case power_t:
2995            case range_t:
2996            case concatenate_t:
2997            case period_ldiff_t:
2998            case period_rdiff_t:
2999            case period_p_intersect_t:
3000            case period_p_normalize_t:
3001            case contains_t:
3002                doParseLeftChainIterative(psql,plocation);
3003                break;
3004            case assignment_t:
3005                doParseLeftChainIterative(psql,plocation);
3006                break;
3007            case sqlserver_proprietary_column_alias_t:
3008                rightOperand.doParse(psql,plocation);
3009                break;
3010            case arithmetic_modulo_t:
3011            case bitwise_exclusive_or_t:
3012            case bitwise_or_t:
3013            case bitwise_and_t:
3014            case bitwise_xor_t:
3015            case exponentiate_t:
3016            case scope_resolution_t:
3017            case at_time_zone_t:
3018            case member_of_t:
3019            case arithmetic_exponentiation_t:
3020                doParseLeftChainIterative(psql,plocation);
3021                break;
3022            case at_local_t:
3023            case day_to_second_t:
3024            case year_to_month_t:
3025                leftOperand.doParse(psql,plocation);
3026                break;
3027            case teradata_at_t:
3028                doParseLeftChainIterative(psql,plocation);
3029                break;
3030            case parenthesis_t:
3031                leftOperand.doParse(psql,plocation);
3032                break;
3033            case simple_comparison_t:
3034                // leftOperand may be null for dangling predicates in CASE expressions
3035                if (leftOperand != null) {
3036                    leftOperand.doParse(psql,plocation);
3037                }
3038                rightOperand.doParse(psql,plocation);
3039                break;
3040            case is_distinct_from_t:
3041                // a IS [NOT] DISTINCT FROM b; leftOperand may be null in the
3042                // predicate-only form (IS DISTINCT FROM b) inside CASE
3043                if (leftOperand != null) {
3044                    leftOperand.doParse(psql,plocation);
3045                }
3046                if (rightOperand != null) {
3047                    rightOperand.doParse(psql,plocation);
3048                }
3049                break;
3050            case group_comparison_t:
3051                doParseLeftChainIterative(psql,plocation);
3052                break;
3053            case in_t:
3054                // leftOperand may be null for dangling predicates in CASE expressions
3055                if (leftOperand != null) {
3056                    leftOperand.doParse(psql,plocation);
3057                }
3058                rightOperand.doParse(psql,plocation);
3059                break;
3060            case floating_point_t:
3061                leftOperand.doParse(psql,plocation);
3062                break;
3063            case logical_xor_t:
3064            case is_t:
3065                doParseLeftChainIterative(psql,plocation);
3066                break;
3067            case logical_not_t:
3068                rightOperand.doParse(psql,plocation);
3069                break;
3070            case null_t:
3071                if (leftOperand != null) {
3072                    leftOperand.doParse(psql,plocation);
3073                }
3074                break;
3075            case is_not_null_t:
3076            case is_true_t:
3077            case is_false_t:
3078            case is_not_true_t:
3079            case is_not_false_t:
3080                leftOperand.doParse(psql,plocation);
3081                break;
3082            case between_t:
3083                // betweenOperand may be null for dangling predicates in CASE expressions
3084                if (betweenOperand != null) {
3085                    betweenOperand.doParse(psql,plocation);
3086                }
3087                leftOperand.doParse(psql,plocation);
3088                rightOperand.doParse(psql,plocation);
3089                break;
3090            case is_of_type_t:
3091                leftOperand.doParse(psql,plocation);
3092                break;
3093            case collate_t: //sql server,postgresql
3094                doParseLeftChainIterative(psql,plocation);
3095                break;
3096            case left_join_t:
3097            case right_join_t:
3098                doParseLeftChainIterative(psql,plocation);
3099                break;
3100            case ref_arrow_t:
3101                if (leftOperand.getExpressionType() == EExpressionType.simple_object_name_t){
3102                    leftOperand.getObjectOperand().setDbObjectType(EDbObjectType.variable);
3103                }
3104                leftOperand.doParse(psql,plocation);
3105                rightOperand.doParse(psql,plocation);
3106                break;
3107            case typecast_t:
3108                leftOperand.doParse(psql,plocation);
3109                break;
3110            case arrayaccess_t:
3111                arrayAccess.doParse(psql,plocation);
3112                break;
3113            case unary_connect_by_root_t:
3114                rightOperand.doParse(psql,plocation);
3115                break;
3116            case interval_t:
3117                intervalExpr.doParse(psql,plocation);
3118                break;
3119            case unary_binary_operator_t:
3120                rightOperand.doParse(psql,plocation);
3121                break;
3122            case left_shift_t:
3123            case right_shift_t:
3124                 doParseLeftChainIterative(psql,plocation);
3125                 break;
3126            case array_constructor_t:
3127                if ((this.subQueryNode != null)&&(subQuery == null)){
3128                    subQuery = new TSelectSqlStatement(psql.dbvendor);
3129                    subQuery.rootNode = subQueryNode;
3130                    subQuery.doParseStatement(psql);
3131                }else if (exprList != null){
3132                    exprList.doParse(psql,plocation);
3133                }else if (arrayConstruct !=null){
3134                    arrayConstruct.doParse(psql,plocation);
3135                }
3136                break;
3137            case objectConstruct_t:
3138                objectConstruct.doParse(psql,plocation);
3139                break;
3140            case row_constructor_t:
3141                if (exprList != null){
3142                    exprList.doParse(psql,plocation);
3143                }
3144                break;
3145            case namedParameter_t:
3146                namedParameter.doParse(psql,plocation);
3147                break;
3148            case positionalParameter_t:
3149                positionalParameter.doParse(psql,plocation);
3150                break;
3151            case collectionArray_t:
3152                collectionArray.doParse(psql,plocation);
3153                break;
3154            case collectionCondition_t:
3155                collectionCondition.doParse(psql,plocation);
3156                break;
3157            case unary_squareroot_t:
3158            case unary_cuberoot_t:
3159            case unary_factorialprefix_t:
3160            case unary_absolutevalue_t:
3161            case unary_bitwise_not_t:
3162                getRightOperand().doParse(psql,plocation);
3163                break;
3164            case unary_factorial_t:
3165                getLeftOperand().doParse(psql,plocation);
3166                break;
3167            case bitwise_shift_left_t:
3168            case bitwise_shift_right_t:
3169                doParseLeftChainIterative(psql,plocation);
3170                break;
3171            case multiset_union_t:
3172            case multiset_union_distinct_t:
3173            case multiset_intersect_t:
3174            case multiset_intersect_distinct_t:
3175            case multiset_except_t:
3176            case multiset_except_distinct_t:
3177                doParseLeftChainIterative(psql,plocation);
3178                break;
3179            case json_get_text:
3180            case json_get_text_at_path:
3181            case json_get_object:
3182            case json_get_object_at_path:
3183            case json_left_contain:
3184            case json_right_contain:
3185            case json_exist:
3186            case json_any_exist:
3187            case json_all_exist:
3188                doParseLeftChainIterative(psql,plocation);
3189                break;
3190            case interpolate_previous_value_t:
3191                doParseLeftChainIterative(psql,plocation);
3192                break;
3193            case text_search_t:
3194            case geo_t:
3195            case network_t:
3196            case json_delete_path:
3197            case json_path_exists:
3198            case json_path_match:
3199                doParseLeftChainIterative(psql,plocation);
3200                break;
3201            case logical_and_t:
3202            case logical_or_t:
3203                doParseLeftChainIterative(psql,plocation);
3204                break;
3205            case submultiset_t:
3206                doParseLeftChainIterative(psql,plocation);
3207                break;
3208            case overlaps_t:
3209                doParseLeftChainIterative(psql,plocation);
3210                break;
3211            case unknown_t:
3212                // Binary expression whose operator has no dedicated type:
3213                // still parse the operands so subqueries and columns inside
3214                // them are analyzed and visible to visitors and the resolver
3215                // (Mantis 4608)
3216                doParseLeftChainIterative(psql,plocation);
3217                break;
3218            case is_a_set_t:
3219                leftOperand.doParse(psql,plocation);
3220                break;
3221            case unnest_t:
3222                leftOperand.doParse(psql,plocation);
3223                break;
3224            case array_t:
3225                if (objectOperand != null){
3226                    psql.linkColumnToTable(objectOperand,plocation);
3227                }
3228
3229                if (getExprList() != null){
3230                    getExprList().doParse(psql,plocation);
3231                }
3232                break;
3233            case fieldselection_t:
3234                if (getLeftOperand() != null){
3235                    getLeftOperand().doParse(psql,plocation);
3236                }else if (getFunctionCall() != null){
3237                    getFunctionCall().doParse(psql,plocation);
3238                }
3239                break;
3240            case lambda_t:
3241                //getLeftOperand().doParse(psql,plocation);
3242                //getRightOperand().doParse(psql,plocation);
3243                break;
3244            case array_access_expr_t:
3245                // Hive/Impala/Spark items[0]: the column records its subscripts, as for items[0].name (plan section
3246                // 4.1, Mantis 4884); any other subscripted expression is parsed as before
3247                if (!doParseSubscriptFieldAccess(psql,plocation)) {
3248                    doParseLeftChainIterative(psql,plocation);
3249                }
3250                break;
3251            case field_access_t:
3252                // Hive items[0].name: a field of an element of the array column items (Mantis 4844)
3253                doParseSubscriptFieldAccess(psql,plocation);
3254                break;
3255            default:;
3256        }
3257    }
3258
3259    /**
3260     * Whether this field access or subscript recorded its path on the column it starts from
3261     * ({@link #doParseSubscriptFieldAccess}).
3262     */
3263    private boolean fieldAccessRecorded = false;
3264
3265    /**
3266     * The chain of a Hive field access over a subscript, outermost first: the field accesses, subscripts and parentheses
3267     * from this expression down to the column they start from, which is last; {@code items} in {@code items[0].name},
3268     * {@code items[0].a[1].b} and {@code (items[0]).name}. Null for any other shape: a chain that does not start from
3269     * a plain column, has no subscript, whose first access after the column is not a subscript, or that reads
3270     * {@code *}. Walked by hand: a long chain must not recurse (Mantis 4844).
3271     */
3272    private ArrayList<TExpression> subscriptFieldChain() {
3273        ArrayList<TExpression> chain = new ArrayList<TExpression>();
3274        TExpression current = this;
3275        while ((current != null) && ((current.getExpressionType() == EExpressionType.field_access_t)
3276                || (current.getExpressionType() == EExpressionType.array_access_expr_t)
3277                || (current.getExpressionType() == EExpressionType.parenthesis_t))) {
3278            if (current.getExpressionType() == EExpressionType.field_access_t) {
3279                TObjectNameList fields = current.getFieldList();
3280                if ((fields == null) || (fields.size() == 0)) return null;
3281                for (int i = 0; i < fields.size(); i++) {
3282                    TObjectName field = fields.getObjectName(i);
3283                    if ((field == null) || (field.getStartToken() == null) || (field.getPartToken() == null)
3284                            || (field.getPartToken().tokentype == ETokenType.ttasterisk)) {
3285                        return null;
3286                    }
3287                }
3288            }
3289            chain.add(current);
3290            current = current.getLeftOperand();
3291        }
3292        if ((current == null) || (current.getExpressionType() != EExpressionType.simple_object_name_t)
3293                || (current.getObjectOperand() == null)) {
3294            return null;
3295        }
3296        // the first access after the column is a subscript: items[0]...
3297        for (int i = chain.size() - 1; i >= 0; i--) {
3298            EExpressionType type = chain.get(i).getExpressionType();
3299            if (type == EExpressionType.parenthesis_t) continue;
3300            if (type != EExpressionType.array_access_expr_t) return null;
3301            break;
3302        }
3303        chain.add(current);
3304        return chain;
3305    }
3306
3307    /**
3308     * Hive {@code items[0].name}: the column {@code items} records the subscripts and the fields after it, as BigQuery's
3309     * grammar records them (Mantis 4833), so that {@link TObjectName#getFieldPathRead()} reads {@code items[*].name},
3310     * and the column and the expressions inside the subscripts are parsed (Mantis 4844). Any other shape is left as it
3311     * was: nothing below it is parsed.
3312     */
3313    private boolean doParseSubscriptFieldAccess(TCustomSqlStatement psql, ESqlClause plocation) {
3314        ArrayList<TExpression> chain = subscriptFieldChain();
3315        if (chain == null) return false;
3316        TExpression base = chain.get(chain.size() - 1);
3317        if (!fieldAccessRecorded) {
3318            if ((base.getObjectOperand().getIndirection() != null) || !recordPathOnColumn(chain)) return false;
3319            fieldAccessRecorded = true;
3320        }
3321        for (int i = 1; i < chain.size() - 1; i++) {
3322            chain.get(i).setLocation(plocation);
3323        }
3324        base.doParse(psql, plocation);
3325        for (int i = chain.size() - 2; i >= 0; i--) {
3326            TExpression node = chain.get(i);
3327            if ((node.getExpressionType() == EExpressionType.array_access_expr_t) && (node.getRightOperand() != null)) {
3328                node.getRightOperand().doParse(psql, plocation);
3329            }
3330        }
3331        return true;
3332    }
3333
3334    /**
3335     * Records the subscripts and fields of {@code chain} ({@link #subscriptFieldChain()}) on its column, in source
3336     * order: an ARRAY_ACCESS per subscript, a QUALIFIED_NAME per field. Every part is made before the column changes,
3337     * so a part that cannot be made leaves the column as it was. The column takes its indirection from the subscripts
3338     * before the first field, as {@code items[0]} gives it, and the rest follows.
3339     */
3340    private static boolean recordPathOnColumn(ArrayList<TExpression> chain) {
3341        TPTNodeList<TIndices> leading = new TPTNodeList<TIndices>();
3342        ArrayList<TIndices> rest = new ArrayList<TIndices>();
3343        for (int i = chain.size() - 2; i >= 0; i--) {
3344            TExpression node = chain.get(i);
3345            if (node.getExpressionType() == EExpressionType.array_access_expr_t) {
3346                TSourceToken open = (node.getLeftOperand() == null) || (node.getLeftOperand().getEndToken() == null)
3347                        ? null : node.getLeftOperand().getEndToken().nextSolidToken();
3348                if ((open == null) || (open.tokencode != '[') || (node.getEndToken() == null)) return false;
3349                TIndices subscript = new TIndices();
3350                subscript.init(null, node.getRightOperand(), null);
3351                subscript.setIndicesType(TIndices.IndicesType.ARRAY_ACCESS);
3352                subscript.setStartToken(open);
3353                subscript.setEndToken(node.getEndToken());
3354                if (rest.isEmpty()) leading.addNode(subscript); else rest.add(subscript);
3355            } else if (node.getExpressionType() == EExpressionType.field_access_t) {
3356                for (int j = 0; j < node.getFieldList().size(); j++) {
3357                    TObjectName name = node.getFieldList().getObjectName(j);
3358                    TSourceToken dot = name.getStartToken().prevSolidToken();
3359                    TIndices field = new TIndices();
3360                    field.init(name, null, null);
3361                    field.setIndicesType(TIndices.IndicesType.QUALIFIED_NAME);
3362                    field.setStartToken(dot != null ? dot : name.getStartToken());
3363                    field.setEndToken(name.getEndToken());
3364                    rest.add(field);
3365                }
3366            }
3367        }
3368        if (leading.size() == 0) return false;
3369        TIndirection indirection = new TIndirection();
3370        indirection.init(leading);
3371        chain.get(chain.size() - 1).getObjectOperand().setIndirection(indirection);
3372        for (TIndices part : rest) {
3373            indirection.getIndices().addNode(part);
3374        }
3375        return true;
3376    }
3377
3378    /**
3379     * The visitors of a recorded Hive {@code items[0].name} ({@link #doParseSubscriptFieldAccess}) visit the left
3380     * operand, as for any other expression; a subscript's own visit reaches the column. Nothing below any other field
3381     * access is visited, as before (Mantis 4844).
3382     */
3383    private void acceptChildrenSubscriptFieldAccess(TParseTreeVisitor v) {
3384        if (fieldAccessRecorded && (leftOperand != null)) {
3385            leftOperand.acceptChildren(v);
3386        }
3387    }
3388
3389    /**
3390     * Check if the expression type is a pure binary type where doParse() only
3391     * calls leftOperand.doParse() + rightOperand.doParse() with no additional logic.
3392     */
3393    public static boolean isPureBinaryForDoParse(EExpressionType type) {
3394        switch (type) {
3395            case arithmetic_plus_t:
3396            case arithmetic_minus_t:
3397            case arithmetic_times_t:
3398            case arithmetic_divide_t:
3399            case power_t:
3400            case range_t:
3401            case concatenate_t:
3402            case period_ldiff_t:
3403            case period_rdiff_t:
3404            case period_p_intersect_t:
3405            case period_p_normalize_t:
3406            case contains_t:
3407            case assignment_t:
3408            case arithmetic_modulo_t:
3409            case bitwise_exclusive_or_t:
3410            case bitwise_or_t:
3411            case bitwise_and_t:
3412            case bitwise_xor_t:
3413            case exponentiate_t:
3414            case scope_resolution_t:
3415            case at_time_zone_t:
3416            case member_of_t:
3417            case arithmetic_exponentiation_t:
3418            case teradata_at_t:
3419            case group_comparison_t:
3420            case logical_and_t:
3421            case logical_or_t:
3422            case logical_xor_t:
3423            case is_t:
3424            case collate_t:
3425            case left_join_t:
3426            case right_join_t:
3427            case left_shift_t:
3428            case right_shift_t:
3429            case bitwise_shift_left_t:
3430            case bitwise_shift_right_t:
3431            case multiset_union_t:
3432            case multiset_union_distinct_t:
3433            case multiset_intersect_t:
3434            case multiset_intersect_distinct_t:
3435            case multiset_except_t:
3436            case multiset_except_distinct_t:
3437            case json_get_text:
3438            case json_get_text_at_path:
3439            case json_get_object:
3440            case json_get_object_at_path:
3441            case json_left_contain:
3442            case json_right_contain:
3443            case json_exist:
3444            case json_any_exist:
3445            case json_all_exist:
3446            case interpolate_previous_value_t:
3447            case submultiset_t:
3448            case overlaps_t:
3449            case array_access_expr_t:
3450            case text_search_t:
3451            case geo_t:
3452            case network_t:
3453            case json_delete_path:
3454            case json_path_exists:
3455            case json_path_match:
3456            case unknown_t:
3457                return true;
3458            default:
3459                return false;
3460        }
3461    }
3462
3463    /**
3464     * Iteratively processes a left-recursive chain of pure binary expressions,
3465     * avoiding deep recursion that would cause StackOverflowError for chains
3466     * with 2000+ operators (e.g., WHERE clauses with 2000+ AND conditions).
3467     *
3468     * Walks the left chain collecting right operands, then processes
3469     * the leftmost leaf and all right operands in left-to-right order.
3470     */
3471    private void doParseLeftChainIterative(TCustomSqlStatement psql, ESqlClause plocation) {
3472        Deque<TExpression> rightChildren = new ArrayDeque<>();
3473        TExpression current = this;
3474        // Descend the left chain while the current node is a pure binary expression
3475        while (current != null && isPureBinaryForDoParse(current.expressionType)) {
3476            current.setLocation(plocation);
3477            if (current.rightOperand != null) {
3478                rightChildren.push(current.rightOperand);
3479            }
3480            current = current.leftOperand;
3481        }
3482        // Process the leftmost non-binary leaf
3483        if (current != null) {
3484            current.doParse(psql, plocation);
3485        }
3486        // Process right children bottom-up (preserves left-to-right order)
3487        while (!rightChildren.isEmpty()) {
3488            rightChildren.pop().doParse(psql, plocation);
3489        }
3490    }
3491
3492    /**
3493     * Iteratively processes a left-recursive chain of pure binary expressions
3494     * for the visitor pattern (acceptChildren), avoiding StackOverflowError.
3495     *
3496     * Preserves the exact preVisit/postVisit ordering of the recursive version:
3497     * preVisit all chain nodes top-down, process leftmost leaf, then bottom-up
3498     * process each right child and call postVisit on the chain node.
3499     *
3500     * Note: preVisit(this) is called by the caller before the switch statement,
3501     * and postVisit(this) is called by the caller after the switch statement.
3502     */
3503    private void acceptChildrenIterativeBinaryChain(TParseTreeVisitor v) {
3504        // Collect the left-recursive chain of pure binary expression nodes
3505        ArrayList<TExpression> chain = new ArrayList<>();
3506        chain.add(this);
3507
3508        TExpression current = this.leftOperand;
3509        while (current != null && isPureBinaryForDoParse(current.expressionType)) {
3510            chain.add(current);
3511            current = current.leftOperand;
3512        }
3513        // `current` is the leftmost non-binary leaf (or null)
3514
3515        // Call preVisit on inner chain nodes top-down (index 0 = this, already preVisited)
3516        for (int i = 1; i < chain.size(); i++) {
3517            v.preVisit(chain.get(i));
3518        }
3519
3520        // Process the leftmost leaf
3521        if (current != null) {
3522            current.acceptChildren(v);
3523        }
3524
3525        // Bottom-up: for each chain node from deepest to shallowest,
3526        // process its right child and call postVisit
3527        for (int i = chain.size() - 1; i >= 1; i--) {
3528            TExpression node = chain.get(i);
3529            if (node.rightOperand != null) {
3530                node.rightOperand.acceptChildren(v);
3531            }
3532            v.postVisit(node);
3533        }
3534
3535        // Process this node's right child
3536        // (postVisit(this) is handled by the caller after the switch)
3537        if (this.rightOperand != null) {
3538            this.rightOperand.acceptChildren(v);
3539        }
3540    }
3541
3542    private EComparisonType comparisonType = EComparisonType.unknown;
3543    private TSourceToken comparisonOperator = null;
3544    private TSourceToken quantifier = null;
3545
3546    public void setQuantifierType(EQuantifierType quantifierType) {
3547        this.quantifierType = quantifierType;
3548    }
3549
3550    public EQuantifierType getQuantifierType() {
3551
3552        return quantifierType;
3553    }
3554
3555    private EQuantifierType quantifierType = EQuantifierType.none;
3556
3557    public EComparisonType getComparisonType() {
3558        return comparisonType;
3559    }
3560
3561    /**
3562     *  one of the following quantifier keywords: SOME, ANY, ALL
3563     * @return SOME, ANY, ALL in group comparison condition.
3564     */
3565    public TSourceToken getQuantifier() {
3566        return quantifier;
3567    }
3568
3569    /**
3570     *
3571     * @return operator used in comparison condition.
3572     */
3573    public TSourceToken getComparisonOperator() {
3574
3575        return comparisonOperator;
3576    }
3577
3578    public void setComparisonOperator(TDummy comparisonOperator) {
3579        if (comparisonOperator == null) return;
3580        for(TSourceToken st : comparisonOperator.tokens){
3581            this.getOperatorTokens().add(st);
3582        }
3583    }
3584
3585    public void setComparisonOperator(TSourceToken comparisonOperator) {
3586        if (comparisonOperator == null) return;
3587        this.comparisonOperator = comparisonOperator;
3588        this.operatorToken = comparisonOperator;
3589        comparisonType = getComparisonType(comparisonOperator);
3590        if ((comparisonOperator.toString().equalsIgnoreCase("="))
3591                && (expressionType == EExpressionType.simple_comparison_t)){
3592            // leftOperand may be null for dangling predicates in CASE expressions
3593            if (leftOperand != null && leftOperand.toString().startsWith("@")){
3594                expressionType = EExpressionType.assignment_t;
3595            }
3596        }
3597    }
3598
3599    public void setQuantifier(TSourceToken quantifier) {
3600        if (quantifier == null) return;
3601        this.quantifier = quantifier;
3602        switch (this.quantifier.tokencode){
3603            case TBaseType.rrw_all:
3604                quantifierType = EQuantifierType.all;
3605                break;
3606            default:
3607                if (this.quantifier.toString().equalsIgnoreCase("any")){
3608                    quantifierType = EQuantifierType.any;
3609                }else if (this.quantifier.toString().equalsIgnoreCase("some")){
3610                    quantifierType = EQuantifierType.some;
3611                }
3612                break;
3613        }
3614    }
3615
3616    public void accept(TParseTreeVisitor v){
3617        v.preVisit(this);
3618        v.postVisit(this);
3619    }
3620
3621    public void acceptChildren(TParseTreeVisitor v){
3622        v.preVisit(this);
3623        switch(expressionType){
3624            case simple_object_name_t:
3625                objectOperand.acceptChildren(v);
3626                break;
3627            case simple_constant_t:
3628                constantOperand.acceptChildren(v);
3629                break;
3630            case list_t:
3631            case collection_constructor_list_t:
3632            case collection_constructor_multiset_t:
3633            case collection_constructor_set_t:
3634            case new_structured_type_t:
3635                if (exprList != null){
3636                    for(int i=0;i<exprList.size();i++){
3637                        exprList.getExpression(i).acceptChildren(v);
3638                    }
3639                }
3640                break;
3641            case function_t:
3642                functionCall.acceptChildren(v);
3643                break;
3644            case type_constructor_t:
3645                if (getExprList() != null){
3646                    getExprList().acceptChildren(v);
3647                }
3648                break;
3649            case cursor_t:
3650            case subquery_t:
3651            case multiset_t:
3652                subQuery.acceptChildren(v);
3653                break;
3654            case case_t:
3655                caseExpression.acceptChildren(v);
3656                break;
3657            case pattern_matching_t:
3658                // leftOperand may be null for dangling predicates in CASE expressions
3659                if (leftOperand != null) {
3660                    leftOperand.acceptChildren(v);
3661                }
3662                rightOperand.acceptChildren(v);
3663                if (likeEscapeOperand != null){
3664                    likeEscapeOperand.acceptChildren(v);
3665                }
3666                break;
3667            case exists_t:
3668                if (subQuery!=null){
3669                    subQuery.acceptChildren(v);
3670                }else{
3671                    // databricks, exists(expr, func)
3672                }
3673
3674                break;
3675            case new_variant_type_t:
3676                newVariantTypeArgumentList.acceptChildren(v);
3677                break;
3678            case unary_plus_t:
3679            case unary_minus_t:
3680            case unary_prior_t:
3681                rightOperand.acceptChildren(v);
3682                break;
3683            case arithmetic_plus_t:
3684            case arithmetic_minus_t:
3685            case arithmetic_times_t:
3686            case arithmetic_divide_t:
3687            case power_t:
3688            case range_t:
3689            case concatenate_t:
3690            case period_ldiff_t:
3691            case period_rdiff_t:
3692            case period_p_intersect_t:
3693            case period_p_normalize_t:
3694            case contains_t:
3695                acceptChildrenIterativeBinaryChain(v);
3696                break;
3697            case assignment_t:
3698                acceptChildrenIterativeBinaryChain(v);
3699                break;
3700            case sqlserver_proprietary_column_alias_t:
3701                rightOperand.acceptChildren(v);
3702                break;
3703            case arithmetic_modulo_t:
3704            case bitwise_exclusive_or_t:
3705            case bitwise_or_t:
3706            case bitwise_and_t:
3707            case bitwise_xor_t:
3708            case exponentiate_t:
3709            case scope_resolution_t:
3710            case at_time_zone_t:
3711            case member_of_t:
3712            case arithmetic_exponentiation_t:
3713                acceptChildrenIterativeBinaryChain(v);
3714                break;
3715            case at_local_t:
3716            case day_to_second_t:
3717            case year_to_month_t:
3718                leftOperand.acceptChildren(v);
3719                break;
3720            case teradata_at_t:
3721                acceptChildrenIterativeBinaryChain(v);
3722                break;
3723            case parenthesis_t:
3724                leftOperand.acceptChildren(v);
3725                break;
3726            case simple_comparison_t:
3727                // leftOperand may be null for dangling predicates in CASE expressions
3728                if (leftOperand != null) {
3729                    leftOperand.acceptChildren(v);
3730                }
3731                rightOperand.acceptChildren(v);
3732                break;
3733            case is_distinct_from_t:
3734                // a IS [NOT] DISTINCT FROM b; leftOperand may be null in the
3735                // predicate-only form (IS DISTINCT FROM b) inside CASE
3736                if (leftOperand != null) {
3737                    leftOperand.acceptChildren(v);
3738                }
3739                if (rightOperand != null) {
3740                    rightOperand.acceptChildren(v);
3741                }
3742                break;
3743            case group_comparison_t:
3744                acceptChildrenIterativeBinaryChain(v);
3745                break;
3746            case in_t:
3747                // leftOperand may be null for dangling predicates in CASE expressions
3748                if (leftOperand != null) {
3749                    leftOperand.acceptChildren(v);
3750                }
3751                rightOperand.acceptChildren(v);
3752                break;
3753            case floating_point_t:
3754                leftOperand.acceptChildren(v);
3755                break;
3756            case logical_and_t:
3757            case logical_or_t:
3758            case logical_xor_t:
3759            case is_t:
3760                acceptChildrenIterativeBinaryChain(v);
3761                break;
3762            case logical_not_t:
3763                rightOperand.acceptChildren(v);
3764                break;
3765            case null_t:
3766            case is_not_null_t:
3767            case is_true_t:
3768            case is_false_t:
3769            case is_not_true_t:
3770            case is_not_false_t:
3771                leftOperand.acceptChildren(v);
3772                break;
3773            case between_t:
3774                if (betweenOperand != null){
3775                    betweenOperand.acceptChildren(v);
3776                }
3777                leftOperand.acceptChildren(v);
3778                rightOperand.acceptChildren(v);
3779                break;
3780            case is_of_type_t:
3781                leftOperand.acceptChildren(v);
3782                break;
3783            case collate_t: //sql server,postgresql
3784                acceptChildrenIterativeBinaryChain(v);
3785                break;
3786            case left_join_t:
3787            case right_join_t:
3788                acceptChildrenIterativeBinaryChain(v);
3789                break;
3790            case ref_arrow_t:
3791                leftOperand.acceptChildren(v);
3792                rightOperand.acceptChildren(v);
3793                break;
3794            case typecast_t:
3795                leftOperand.acceptChildren(v);
3796                break;
3797            case arrayaccess_t:
3798                arrayAccess.acceptChildren(v);
3799                break;
3800            case unary_connect_by_root_t:
3801                rightOperand.acceptChildren(v);
3802                break;
3803            case interval_t:
3804                intervalExpr.acceptChildren(v);
3805                break;
3806            case unary_binary_operator_t:
3807                rightOperand.acceptChildren(v);
3808                break;
3809            case left_shift_t:
3810            case right_shift_t:
3811                acceptChildrenIterativeBinaryChain(v);
3812                break;
3813            case array_constructor_t:
3814                if (subQuery != null){
3815                    subQuery.acceptChildren(v);
3816                }else if (exprList != null){
3817                    exprList.acceptChildren(v);
3818                }else if (arrayConstruct != null){
3819                    arrayConstruct.acceptChildren(v);
3820                }
3821                break;
3822            case row_constructor_t:
3823                if (exprList != null){
3824                    exprList.acceptChildren(v);
3825                }
3826                break;
3827            case unary_squareroot_t:
3828            case unary_cuberoot_t:
3829            case unary_factorialprefix_t:
3830            case unary_absolutevalue_t:
3831            case unary_bitwise_not_t:
3832                getRightOperand().acceptChildren(v);
3833                break;
3834            case unary_factorial_t:
3835                getLeftOperand().acceptChildren(v);
3836                break;
3837            case bitwise_shift_left_t:
3838            case bitwise_shift_right_t:
3839                acceptChildrenIterativeBinaryChain(v);
3840                break;
3841            case multiset_union_t:
3842            case multiset_union_distinct_t:
3843            case multiset_intersect_t:
3844            case multiset_intersect_distinct_t:
3845            case multiset_except_t:
3846            case multiset_except_distinct_t:
3847                acceptChildrenIterativeBinaryChain(v);
3848                break;
3849            case json_get_text:
3850            case json_get_text_at_path:
3851            case json_get_object:
3852            case json_get_object_at_path:
3853            case json_left_contain:
3854            case json_right_contain:
3855            case json_exist:
3856            case json_any_exist:
3857            case json_all_exist:
3858                acceptChildrenIterativeBinaryChain(v);
3859                break;
3860            case interpolate_previous_value_t:
3861                acceptChildrenIterativeBinaryChain(v);
3862                break;
3863            case text_search_t:
3864            case geo_t:
3865            case network_t:
3866            case json_delete_path:
3867            case json_path_exists:
3868            case json_path_match:
3869                acceptChildrenIterativeBinaryChain(v);
3870                break;
3871            case submultiset_t:
3872                acceptChildrenIterativeBinaryChain(v);
3873                break;
3874            case overlaps_t:
3875                acceptChildrenIterativeBinaryChain(v);
3876                break;
3877            case unknown_t:
3878                // keep unmapped binary operators traversable (Mantis 4608)
3879                acceptChildrenIterativeBinaryChain(v);
3880                break;
3881            case is_a_set_t:
3882                leftOperand.acceptChildren(v);
3883                break;
3884            case array_t:
3885                if (getExprList() != null){
3886                    getExprList().acceptChildren(v);
3887                }
3888                break;
3889            case lambda_t:
3890                getLeftOperand().acceptChildren(v);
3891                getRightOperand().acceptChildren(v);
3892                break;
3893            case field_access_t:
3894                // Hive items[0].name: the visitors reach the column items (Mantis 4844)
3895                acceptChildrenSubscriptFieldAccess(v);
3896                break;
3897            default:;
3898        }
3899
3900        v.postVisit(this);
3901    }
3902
3903    /**
3904     * expression type such as column reference is a leaf expression while subtract expression
3905     * is not a leaf expression. Usually, non-leaf expression should including both {@link #getLeftOperand()}
3906     * and {@link #getRightOperand()}.
3907     * @return leaf expression or not.
3908     */
3909    public boolean isLeaf(){
3910        return isLeafExpr(this);
3911    }
3912
3913
3914    public boolean isLeafExpr(TParseTreeNode pnode){
3915        boolean ret = true;
3916        if (pnode == null) return ret;
3917        if (!(pnode instanceof TExpression)) return ret;
3918        TExpression e = (TExpression)pnode;
3919
3920        if ((onlyAndOrIsNonLeaf) &&(!((e.getExpressionType()==EExpressionType.logical_and_t)||(e.getExpressionType()==EExpressionType.logical_or_t)))) return ret;
3921
3922        switch (e.getExpressionType()){
3923            case case_t:
3924            case simple_object_name_t:
3925            case simple_constant_t:
3926            case simple_source_token_t:
3927            case group_t:
3928            case list_t:
3929            case collection_constructor_list_t:
3930            case collection_constructor_multiset_t:
3931            case collection_constructor_set_t:
3932            case cursor_t:
3933            case function_t:
3934            case type_constructor_t:
3935            case subquery_t:
3936            case multiset_t:
3937            case object_access_t:
3938            case place_holder_t:
3939            case is_of_type_t:
3940            case exists_t:
3941            case arrayaccess_t:
3942            case interval_t:
3943            case new_structured_type_t:
3944            case new_variant_type_t:
3945            case member_of_t:
3946            case submultiset_t:
3947            case execute_stmt_t:
3948            case cursor_attribute_t:
3949                return ret;
3950            default:
3951        }
3952        //if(e.getExpressionType() == TExpression.datetimeExprOperator) return ret;
3953        //if(e.getExpressionType() == TExpression.intervalExprOperator) return ret;
3954        //if(e.getExpressionType() == TExpression.modelExprOperator) return ret;
3955        //if(e.getExpressionType() == TExpression.typeconstructorExprOperator) return ret;
3956        //if(e.getExpressionType() == TExpression.patternMatchingExprOperator) return ret;
3957
3958        if (e.getLeftOperand() != null){
3959            ret = !(e.getLeftOperand() instanceof TExpression);
3960        }
3961        if (e.getRightOperand() != null){
3962            ret = !(e.getRightOperand() instanceof TExpression);
3963        }
3964
3965        return ret;
3966    }
3967
3968    private Stack exprStack = null;
3969
3970    private Stack getExprStack() {
3971        if (exprStack == null){
3972            exprStack = new Stack();
3973        }
3974        return exprStack;
3975    }
3976
3977    // used in  PreOrderTraverse only,  InOrderTraverse  and PostOrderTraverse has already visit subtree.
3978    private boolean visitSubTree = true;
3979
3980
3981    public void setVisitSubTree(boolean visitSubTree) {
3982        this.visitSubTree = visitSubTree;
3983    }
3984
3985    public boolean isVisitSubTree() {
3986
3987        return visitSubTree;
3988    }
3989
3990    private boolean checkIsVisitSubTree(TParseTreeNode node){
3991        boolean ret = !this.isLeafExpr(node);
3992        if (ret){
3993            ret = ((TExpression)node).isVisitSubTree();
3994        }
3995        return ret;
3996    }
3997
3998
3999    public void setWindowSpecification(TWindowDef windowSpecification){
4000        if (this.getExpressionType() != EExpressionType.function_t) return;
4001        this.getFunctionCall().setWindowDef(windowSpecification);
4002
4003    }
4004
4005    /**
4006     * Traverse expression in pre Order.
4007     * @param ev user defined visitor
4008     */
4009    public void preOrderTraverse(IExpressionVisitor ev){
4010
4011
4012        if (this.isLeaf()){
4013            ev.exprVisit(this,true);
4014        }else{
4015            getExprStack().push(this);
4016        }
4017
4018        TParseTreeNode node = null;
4019        while(getExprStack().size() > 0){
4020            node = (TParseTreeNode)getExprStack().peek();
4021
4022            while(node != null){
4023                if (!ev.exprVisit(node,this.isLeafExpr(node))) {
4024                    return;
4025                }
4026
4027                if (this.isLeafExpr(node)) {
4028                    this.getExprStack().push(null);
4029                }else if (!this.checkIsVisitSubTree(node)){
4030                    this.getExprStack().push(null);
4031                }else{
4032                    this.getExprStack().push(((TExpression)node).getLeftOperand());
4033                }
4034                node = (TParseTreeNode)this.getExprStack().peek();
4035            }
4036
4037            // pop up the dummyOperator expression node
4038            this.getExprStack().pop();
4039
4040            if (this.getExprStack().size() > 0){
4041                node = (TParseTreeNode)this.getExprStack().pop();
4042                
4043                if (this.isLeafExpr(node)) {
4044                    this.getExprStack().push(null);
4045                }else if (!this.checkIsVisitSubTree(node)){
4046                    this.getExprStack().push(null);
4047                }else{
4048                    this.getExprStack().push(((TExpression)node).getRightOperand());
4049                }
4050
4051            }
4052
4053        } //while
4054
4055
4056    }
4057
4058    /**
4059     * Traverse expression in In Order.
4060     * @param ev user defined visitor
4061     */
4062    public void inOrderTraverse(IExpressionVisitor ev){
4063
4064        if (this.isLeaf()){
4065            ev.exprVisit(this,true);
4066        }else{
4067            getExprStack().push(this);
4068        }
4069
4070        TParseTreeNode node = null;
4071        while(getExprStack().size() > 0){
4072            node = (TParseTreeNode)getExprStack().peek();
4073
4074            while(node != null){
4075
4076                if (this.isLeafExpr(node)) {
4077                    this.getExprStack().push(null);
4078                }else{
4079                    this.getExprStack().push(((TExpression)node).getLeftOperand());
4080                }
4081                node = (TParseTreeNode)this.getExprStack().peek();
4082            }
4083
4084            // pop up the dummyOperator expression node
4085            this.getExprStack().pop();
4086
4087            if (this.getExprStack().size() > 0){
4088                node = (TParseTreeNode)this.getExprStack().pop();
4089
4090                if (!ev.exprVisit(node,this.isLeafExpr(node))) {
4091                    return;
4092                }
4093
4094                if (this.isLeafExpr(node)) {
4095                    this.getExprStack().push(null);
4096                }else{
4097                    this.getExprStack().push(((TExpression)node).getRightOperand());
4098                }
4099
4100            }
4101
4102        } //while
4103
4104    }
4105
4106    /**
4107     * Traverse expression in post order.
4108     * @param ev user defined visitor
4109     */
4110    public void postOrderTraverse(IExpressionVisitor ev){
4111
4112        final int ctNone = 0;
4113        final int ctL = 1;
4114        final int ctR = 2;
4115
4116        if (this.isLeaf()){
4117            ev.exprVisit(this,true);
4118        }else{
4119            getExprStack().push(this);
4120        }
4121
4122        TParseTreeNode node = null;
4123
4124        while(getExprStack().size() > 0){
4125            node = (TParseTreeNode)getExprStack().peek();
4126
4127            while(node != null){
4128
4129                if (this.isLeafExpr(node)) {
4130                    this.getExprStack().push(null);
4131                }else{
4132                    this.getExprStack().push(((TExpression)node).getLeftOperand());
4133                }
4134                node = (TParseTreeNode)this.getExprStack().peek();
4135                if (node != null){
4136                    node.setDummyTag(ctL);
4137                }
4138            }
4139
4140            // pop up the dummyOperator expression node
4141            this.getExprStack().pop();
4142            node = (TParseTreeNode)this.getExprStack().peek();
4143
4144            while((this.getExprStack().size() > 0) &&(node.getDummyTag() == ctR)){
4145                node = (TParseTreeNode)this.getExprStack().pop();
4146                node.setDummyTag(ctNone); //restore tag so next this expression will be traversed correctly
4147                if (!ev.exprVisit(node,this.isLeafExpr(node))) {
4148                    return;
4149                }
4150
4151                if (this.getExprStack().size() > 0){
4152                    node = (TParseTreeNode)this.getExprStack().peek();
4153                }else{
4154                    break;
4155                }
4156            }
4157
4158            if (this.getExprStack().size() > 0){
4159                node = (TParseTreeNode)this.getExprStack().peek();
4160                node.setDummyTag(ctR);
4161                if (this.isLeafExpr(node)){
4162                    this.getExprStack().push(null);
4163                }else{
4164                 this.getExprStack().push(((TExpression)node).getRightOperand());
4165                }
4166            }
4167
4168        }//while
4169
4170    }
4171
4172    /**
4173     * if original expr is f &gt; 1, and call addANDCondition("f2 &gt; 2")
4174     * expression will be: f &gt; 1 and f2&gt; 2
4175     * @param condition
4176     */
4177    public void addANDCondition(String condition){
4178        //appendString(" and "+condition);
4179        setString("("+this.toString()+") and "+condition);
4180    }
4181
4182    /**
4183     * if original expr is f &gt; 1, and call addORCondition("f2 &gt; 2")
4184     * expression will be: f &gt; 1 or f2 &gt;2
4185     *
4186     * @param condition
4187     */
4188    public void addORCondition(String condition){
4189        //appendString(" or "+condition);
4190        setString("("+this.toString()+") or "+condition);
4191    }
4192
4193
4194    /**
4195     * remove this expression from it's parent expr.
4196     * if itself is the top level expression, then remove it from parse tree
4197     * <p>f1 &gt; 1 and f2 &gt; 2, after remove f2 &gt; 2, parent expression will be changed to: f1 &gt; 1
4198     * <p> If we need to remove condition f &gt; 1 from where clause: where f &gt; 1,
4199     * Here f &gt; 1 is the top level expression, after remove it from where clause, only  WHERE keyword left in where clause.
4200     */
4201
4202    public void removeMe(){
4203        if (this.getExpressionType() == EExpressionType.removed_t) return;
4204        this.setExpressionType(EExpressionType.removed_t);
4205
4206        TExpression parentExpr = this.getParentExpr();
4207        if (parentExpr == null){
4208            this.removeTokens();
4209            return;
4210        }
4211
4212        switch (parentExpr.getExpressionType()){
4213            case list_t: // (1,2,3) in (column1,column2,column3)
4214                // remove column1 will break this expr, so need to remove parent expr of list_t as well.
4215                //if (parentExpr.getParentExpr() != null) removeExpr(parentExpr.getParentExpr());
4216                parentExpr.removeMe();
4217                break;
4218            case parenthesis_t:
4219                parentExpr.removeMe();
4220                break;
4221            case arithmetic_plus_t:
4222            case arithmetic_minus_t:
4223            case arithmetic_times_t:
4224            case arithmetic_divide_t:
4225            case arithmetic_modulo_t:
4226            case bitwise_exclusive_or_t:
4227            case bitwise_or_t:
4228            case bitwise_and_t:
4229            case bitwise_xor_t:
4230            case logical_xor_t:
4231            case concatenate_t:
4232            case logical_and_t:
4233            case logical_or_t:
4234                if (this.getNodeStatus() == ENodeStatus.nsRemoved){
4235                    // this node is removed cascade
4236                    if (this.isLeftOperandOfParent()){
4237                        if ((this.getParentExpr().getRightOperand() != null)&&(this.getParentExpr().getRightOperand().getNodeStatus() != ENodeStatus.nsRemoved)){
4238                            this.getParentExpr().refreshAllNodesTokenCount();
4239                            this.getParentExpr().removeTokensBetweenToken(this.getParentExpr().getStartToken(),this.getParentExpr().getRightOperand().getStartToken().getPrevTokenInChain());
4240                            this.getParentExpr().updateNodeWithTheSameStartToken(TParseTreeNode.nodeChangeStartToken ,this.getParentExpr().getRightOperand().getStartToken());
4241                        }
4242                    }else if (this.isRightOperandOfParent()){
4243                        if ((this.getParentExpr().getLeftOperand() != null)&&(this.getParentExpr().getLeftOperand().getNodeStatus() != ENodeStatus.nsRemoved)){
4244                            this.getParentExpr().refreshAllNodesTokenCount();
4245                            this.getParentExpr().removeTokensBetweenToken(this.getParentExpr().getLeftOperand().getEndToken().getNextTokenInChain(),this.getParentExpr().getEndToken());
4246                            this.getParentExpr().updateMeNodeWithTheSameEndToken(TParseTreeNode.nodeChangeEndToken ,this.getParentExpr().getLeftOperand().getEndToken());
4247                        }
4248                    }
4249                }else{
4250                    TParseTreeNode.removeTokensBetweenNodes(parentExpr.leftOperand,parentExpr.rightOperand);
4251                }
4252
4253                this.removeTokens();
4254                if (parentExpr.getNodeStatus() == ENodeStatus.nsRemoved){
4255                    parentExpr.removeMe();
4256                }
4257                break;
4258            case simple_comparison_t:
4259            case is_distinct_from_t:
4260            case group_comparison_t:
4261            case in_t:
4262                parentExpr.removeMe();
4263                break;
4264            case between_t:
4265                parentExpr.removeMe();
4266                break;
4267            case unary_plus_t:
4268            case unary_minus_t:
4269            case unary_prior_t:
4270            case pattern_matching_t:
4271            case power_t:
4272            case range_t:
4273            case period_ldiff_t:
4274            case period_rdiff_t:
4275            case period_p_intersect_t:
4276            case period_p_normalize_t:
4277            case contains_t:
4278            case assignment_t:
4279            case sqlserver_proprietary_column_alias_t:
4280            case scope_resolution_t:
4281            case at_time_zone_t:
4282            case member_of_t:
4283            case arithmetic_exponentiation_t:
4284            case submultiset_t:
4285            case overlaps_t:
4286            case at_local_t:
4287            case day_to_second_t:
4288            case year_to_month_t:
4289            case exponentiate_t:
4290            case floating_point_t:
4291            case is_t:
4292            case logical_not_t:
4293            case null_t:
4294            case is_not_null_t:
4295            case is_true_t:
4296            case is_false_t:
4297            case is_not_true_t:
4298            case is_not_false_t:
4299            case is_of_type_t:
4300            case collate_t: //sql server,postgresql
4301            case left_join_t:
4302            case right_join_t:
4303            case ref_arrow_t:
4304            case typecast_t:
4305            case arrayaccess_t:
4306            case unary_connect_by_root_t:
4307            case interval_t:
4308            case unary_binary_operator_t:
4309            case left_shift_t:
4310            case right_shift_t:
4311            case array_constructor_t:
4312            case objectConstruct_t:
4313            case row_constructor_t:
4314            case namedParameter_t:
4315            case positionalParameter_t:
4316            case collectionArray_t:
4317            case collectionCondition_t:
4318            case unary_squareroot_t:
4319            case unary_cuberoot_t:
4320            case unary_factorialprefix_t:
4321            case unary_absolutevalue_t:
4322            case unary_bitwise_not_t:
4323            case unary_factorial_t:
4324            case bitwise_shift_left_t:
4325            case bitwise_shift_right_t:
4326            case multiset_union_t:
4327            case multiset_union_distinct_t:
4328            case multiset_intersect_t:
4329            case multiset_intersect_distinct_t:
4330            case multiset_except_t:
4331            case multiset_except_distinct_t:
4332            case json_get_text:
4333            case json_get_text_at_path:
4334            case json_get_object:
4335            case json_get_object_at_path:
4336            case json_left_contain:
4337            case json_right_contain:
4338            case json_exist:
4339            case json_any_exist:
4340            case json_all_exist:
4341            case interpolate_previous_value_t:
4342            case unnest_t:
4343                if (leftOperand != null){
4344                    leftOperand.removeMe();
4345                }else if (rightOperand != null){
4346                    rightOperand.removeMe();
4347                }
4348
4349                break;
4350            case lambda_t:
4351                leftOperand.removeMe();
4352                rightOperand.removeMe();
4353                break;
4354            case teradata_at_t:
4355                leftOperand.removeMe();
4356                rightOperand.removeMe();
4357                break;
4358            default:
4359                parentExpr.removeMe();
4360                break;
4361        }
4362    }
4363
4364public void remove2(){
4365    if (TParseTreeNode.doubleLinkedTokenListToString){
4366        removeMe();
4367    }else{
4368        if (parentExpr == null){
4369            removeAllMyTokensFromTokenList(null);
4370        }else if ((parentExpr.getExpressionType() == EExpressionType.logical_and_t)
4371                ||(parentExpr.getExpressionType() == EExpressionType.logical_or_t))
4372        {
4373            removeAllMyTokensFromTokenList(parentExpr.getOperatorToken());
4374            if ((parentExpr.getLeftOperand().getStartToken() == null)&&(parentExpr.getRightOperand().getStartToken() == null)){
4375                parentExpr.remove2();
4376            }
4377        }else if (parentExpr.getExpressionType() == EExpressionType.parenthesis_t){
4378            removeAllMyTokensFromTokenList(null);
4379            parentExpr.remove2();
4380        }else{
4381            removeAllMyTokensFromTokenList(null);
4382        }
4383    }
4384}
4385
4386    public void remove(){
4387
4388        if (this.getExpressionType() == EExpressionType.removed_t) return;
4389
4390        this.setExpressionType(EExpressionType.removed_t);
4391        TExpression parentExpr = this.getParentExpr();
4392
4393        if (parentExpr == null) return;
4394
4395        switch (parentExpr.getExpressionType()){
4396            case list_t: // (1,2,3) in (column1,column2,column3)
4397                // remove column1 will break this expr, so need to remove parent expr of list_t as well.
4398                //if (parentExpr.getParentExpr() != null) removeExpr(parentExpr.getParentExpr());
4399                parentExpr.remove();
4400                break;
4401            case pattern_matching_t:
4402                parentExpr.remove();
4403                break;
4404            case unary_plus_t:
4405            case unary_minus_t:
4406            case unary_prior_t:
4407                parentExpr.remove();
4408                break;
4409            case arithmetic_plus_t:
4410            case arithmetic_minus_t:
4411            case arithmetic_times_t:
4412            case arithmetic_divide_t:
4413            case power_t:
4414            case range_t:
4415            case period_ldiff_t:
4416            case period_rdiff_t:
4417            case period_p_intersect_t:
4418            case period_p_normalize_t:
4419            case contains_t:
4420                parentExpr.remove();
4421                break;
4422            case assignment_t:
4423                parentExpr.remove();
4424                break;
4425            case sqlserver_proprietary_column_alias_t:
4426                parentExpr.remove();
4427                break;
4428            case arithmetic_modulo_t:
4429            case bitwise_exclusive_or_t:
4430            case bitwise_or_t:
4431            case bitwise_and_t:
4432            case bitwise_xor_t:
4433            case exponentiate_t:
4434            case scope_resolution_t:
4435            case at_time_zone_t:
4436            case member_of_t:
4437            case arithmetic_exponentiation_t:
4438            case submultiset_t:
4439            case overlaps_t:
4440                parentExpr.remove();
4441                break;
4442            case at_local_t:
4443            case day_to_second_t:
4444            case year_to_month_t:
4445                parentExpr.remove();
4446                break;
4447            case parenthesis_t:
4448                parentExpr.remove();
4449                break;
4450            case simple_comparison_t:
4451            case is_distinct_from_t:
4452                parentExpr.remove();
4453                break;
4454            case group_comparison_t:
4455                parentExpr.remove();
4456                break;
4457            case in_t:
4458                parentExpr.remove();
4459                break;
4460            case floating_point_t:
4461                parentExpr.remove();
4462                break;
4463            case logical_xor_t:
4464            case is_t:
4465                parentExpr.remove();
4466                break;
4467            case logical_not_t:
4468                parentExpr.remove();
4469                break;
4470            case null_t:
4471            case is_not_null_t:
4472            case is_true_t:
4473            case is_false_t:
4474            case is_not_true_t:
4475            case is_not_false_t:
4476                parentExpr.remove();
4477                break;
4478            case between_t:
4479                parentExpr.remove();
4480                break;
4481            case is_of_type_t:
4482                parentExpr.remove();
4483                break;
4484            case collate_t: //sql server,postgresql
4485                parentExpr.remove();
4486                break;
4487            case left_join_t:
4488            case right_join_t:
4489                parentExpr.remove();
4490                break;
4491            case ref_arrow_t:
4492                parentExpr.remove();
4493                break;
4494            case typecast_t:
4495                parentExpr.remove();
4496                break;
4497            case arrayaccess_t:
4498                parentExpr.remove();
4499                break;
4500            case unary_connect_by_root_t:
4501                parentExpr.remove();
4502                break;
4503            case interval_t:
4504                parentExpr.remove();
4505                break;
4506            case unary_binary_operator_t:
4507                parentExpr.remove();
4508                break;
4509            case left_shift_t:
4510            case right_shift_t:
4511                parentExpr.remove();
4512                break;
4513            case array_constructor_t:
4514                parentExpr.remove();
4515                break;
4516            case objectConstruct_t:
4517                parentExpr.remove();
4518                break;
4519            case row_constructor_t:
4520                parentExpr.remove();
4521                break;
4522            case namedParameter_t:
4523                parentExpr.remove();
4524                break;
4525            case positionalParameter_t:
4526                parentExpr.remove();
4527                break;
4528            case collectionArray_t:
4529                parentExpr.remove();
4530                break;
4531            case collectionCondition_t:
4532                parentExpr.remove();
4533                break;
4534            case unary_squareroot_t:
4535            case unary_cuberoot_t:
4536            case unary_factorialprefix_t:
4537            case unary_absolutevalue_t:
4538            case unary_bitwise_not_t:
4539                parentExpr.remove();
4540                break;
4541            case unary_factorial_t:
4542                parentExpr.remove();
4543                break;
4544            case bitwise_shift_left_t:
4545            case bitwise_shift_right_t:
4546                parentExpr.remove();
4547                break;
4548            case multiset_union_t:
4549            case multiset_union_distinct_t:
4550            case multiset_intersect_t:
4551            case multiset_intersect_distinct_t:
4552            case multiset_except_t:
4553            case multiset_except_distinct_t:
4554                parentExpr.remove();
4555                break;
4556            case json_get_text:
4557            case json_get_text_at_path:
4558            case json_get_object:
4559            case json_get_object_at_path:
4560            case json_left_contain:
4561            case json_right_contain:
4562            case json_exist:
4563            case json_any_exist:
4564            case json_all_exist:
4565            case lambda_t:
4566                parentExpr.remove();
4567                break;
4568            case interpolate_previous_value_t:
4569                parentExpr.remove();
4570                break;
4571            case concatenate_t:
4572            case logical_and_t:
4573            case logical_or_t:
4574                if (this == parentExpr.getLeftOperand()){
4575                    parentExpr.getRightOperand().copyTo(parentExpr);
4576                }else if (this == parentExpr.getRightOperand()){
4577                    parentExpr.getLeftOperand().copyTo(parentExpr);
4578                }
4579
4580                break;
4581            case unnest_t:
4582                leftOperand.remove();
4583                break;
4584            default:
4585                parentExpr.remove();
4586                break;
4587        }
4588
4589    }
4590
4591    public void copyTo(TExpression target){
4592        target.setExpressionType(this.getExpressionType());
4593        target.setLeftOperand(this.getLeftOperand());
4594        target.setRightOperand(this.getRightOperand());
4595        target.setObjectOperand(this.getObjectOperand());
4596        target.setFunctionCall(this.getFunctionCall());
4597        target.setSubQuery(this.getSubQuery());
4598        target.setConstantOperand(this.getConstantOperand());
4599        target.setExprList(this.getExprList());
4600        target.setOperatorToken(this.getOperatorToken());
4601        target.setComparisonOperator(this.getComparisonOperator());
4602        target.setBetweenOperand(this.getBetweenOperand());
4603        target.setCaseExpression(this.getCaseExpression());
4604
4605        target.setLikeEscapeOperand(this.getLikeEscapeOperand());
4606        target.setNotToken(this.getNotToken());
4607        target.setQuantifier(this.getQuantifier());
4608        target.setQuantifierType(this.getQuantifierType());
4609
4610    }
4611
4612    public static TExpression mergeObjectNameList(TExpression expr, TObjectNameList objectNameList){
4613        TExpression ret = null;
4614        if (expr.expressionType == EExpressionType.simple_object_name_t){
4615            TObjectName objectName = expr.getObjectOperand();
4616            objectName.appendObjectName(objectNameList.getObjectName(0));
4617            ret = expr;
4618        }
4619        return ret;
4620    }
4621
4622
4623    private TColumnDefinitionList colDefList = null;
4624    public TColumnDefinitionList getcolDefList() {
4625                return colDefList;
4626        }
4627
4628    public final static int  BigAndOrNestLevel = 100;
4629    /**
4630     * @deprecated As of v1.4.3.0, replaced by {@link EExpressionType#not_initialized_yet_t}
4631     */
4632    public final static int unknown = 0;
4633
4634    /**
4635     * Addition: expr + expr
4636     * <p>expr can be accessed via {@link #getLeftOperand()} and {@link #getRightOperand()}
4637     */
4638    /**
4639     * @deprecated As of v1.4.3.0, replaced by {@link EExpressionType#arithmetic_plus_t}
4640     */
4641    public final static int PLUS        = 1;
4642
4643    /**
4644     * syntax: expr - expr
4645     * <p>expr can be accessed via {@link #getLeftOperand()} and {@link #getRightOperand()}
4646     */
4647    /**
4648     * @deprecated As of v1.4.3.0, replaced by {@link EExpressionType#arithmetic_minus_t}
4649     */
4650    public final static int MINUS       = 2;
4651
4652    /**
4653     * syntax: expr * expr
4654     * <p>expr can be accessed via {@link #getLeftOperand()} and {@link #getRightOperand()}
4655     */
4656    /**
4657     * @deprecated As of v1.4.3.0, replaced by {@link EExpressionType#arithmetic_times_t}
4658     */
4659    public final static int TIMES       = 3;
4660
4661    /**
4662     * syntax: expr / expr
4663     * <p>expr can be accessed via {@link #getLeftOperand()} and {@link #getRightOperand()}
4664     */
4665    /**
4666     * @deprecated As of v1.4.3.0, replaced by {@link EExpressionType#arithmetic_divide_t}
4667     */
4668    public final static int DIVIDE      = 4;
4669
4670    /**
4671     * Links two string operands to form a string expression.
4672     * <p>syntax: expr || expr,
4673     * <p>expr can be accessed via {@link #getLeftOperand()} and {@link #getRightOperand()}
4674     */
4675    /**
4676     * @deprecated As of v1.4.3.0, replaced by {@link EExpressionType#concatenate_t}
4677     */
4678    public final static int CONCATENATE = 5;
4679
4680    /**
4681     * SQL SERVER,TERADATE(mod)
4682     * <p>expr can be accessed via {@link #getLeftOperand()} and {@link #getRightOperand()}
4683     */
4684    /**
4685     * @deprecated As of v1.4.3.0, replaced by {@link EExpressionType#arithmetic_modulo_t}
4686     */
4687    public final static int MODULO = 6; //
4688
4689    /**
4690     * Used in set clause of update statement.
4691     * <p> Or, assign argument in postgresql function argument like this:
4692     * <p> param_name ASSIGN_SIGN basic_expr
4693     * <P> expr can be accessed via {@link #getLeftOperand()} and {@link #getRightOperand()}
4694     */
4695    /**
4696     * @deprecated As of v1.4.3.0, replaced by {@link EExpressionType#assignment_t}
4697     */
4698    public final static int ASSIGNMENT = 7; //
4699
4700    /**
4701     * SQL SERVER, postgresql
4702     * <p>expr can be accessed via {@link #getLeftOperand()} and {@link #getRightOperand()}
4703     */
4704    /**
4705     * @deprecated As of v1.4.3.0, replaced by {@link EExpressionType#bitwise_and_t}
4706     */
4707    public final static int BITWISE_AND = 8;
4708
4709    /**
4710     * SQL SERVER, postgresql
4711     * <p>expr can be accessed via {@link #getLeftOperand()} and {@link #getRightOperand()}
4712     */
4713    /**
4714     * @deprecated As of v1.4.3.0, replaced by {@link EExpressionType#bitwise_or_t}
4715     */
4716    public final static int BITWISE_OR = 9;
4717
4718    /**
4719     * MySQL, postgresql
4720     * <p>expr can be accessed via {@link #getLeftOperand()} and {@link #getRightOperand()}
4721     */
4722    /**
4723     * @deprecated As of v1.4.3.0, replaced by {@link EExpressionType#bitwise_xor_t}
4724     */
4725    public final static int BITWISE_XOR = 10; //
4726
4727    /**
4728     * SQL SERVER
4729     * <p>expr can be accessed via {@link #getLeftOperand()} and {@link #getRightOperand()}
4730     */
4731    /**
4732     * @deprecated As of v1.4.3.0, replaced by {@link EExpressionType#bitwise_exclusive_or_t}
4733     */
4734    public final static int BITWISE_EXCLUSIVE_OR = 11;
4735
4736    /**
4737     * SQL SERVER
4738     * <p>The scope resolution operator :: provides access to static members of a compound data type,
4739     * SELECT @hid = hierarchyid::GetRoot();
4740     * <p>Not implemented yet,
4741     */
4742    /**
4743     * @deprecated As of v1.4.3.0, replaced by {@link EExpressionType#scope_resolution_t}
4744     */
4745    public final static int SCOPE_RESOLUTION = 12; //
4746
4747    /**
4748     * teradata ** , Postgresql ^
4749     * <p>expr can be accessed via {@link #getLeftOperand()} and {@link #getRightOperand()}
4750     */
4751    /**
4752     * @deprecated As of v1.4.3.0, replaced by {@link EExpressionType#exponentiate_t}
4753     */
4754    public final static int  EXPONENTIATE = 13; //
4755
4756    /**
4757     * sql server 2008 +=,-=,*=,/=,%=
4758     * <p>expr can be accessed via {@link #getLeftOperand()} and {@link #getRightOperand()}
4759     */
4760    /**
4761     * @deprecated As of v1.4.3.0, replaced by {@link EExpressionType#arithmetic_compound_operator_t}
4762     */
4763    public final static int  compoundAssignment = 14;
4764
4765    /**
4766     * specifies a column, pseudocolumn, sequence number,
4767     * value can be get via {@link #getObjectOperand()} which is type of {@link TObjectName}.
4768     */
4769    /**
4770     * @deprecated As of v1.4.3.0, replaced by {@link EExpressionType#simple_object_name_t}
4771     */
4772    public final static int simpleObjectname = 15;
4773
4774    /**
4775     * specifies a constant,
4776     * value can be get via {@link #getConstantOperand()}
4777     */
4778    /**
4779     * @deprecated As of v1.4.3.0, replaced by {@link EExpressionType#simple_constant_t}
4780     */
4781    public final static int simpleConstant = 16;
4782
4783    /**
4784     * specifies a null,
4785     * value can be get via {@link #getSourcetokenOperand()} which is type of {@link TSourceToken}.
4786     */
4787    /**
4788     * @deprecated As of v1.4.3.0, replaced by {@link EExpressionType#simple_source_token_t}
4789     */
4790    public final static int simpleSourcetoken = 17;
4791
4792    /**
4793     * expression with parenthesis,
4794     * expr can be get via {@link #getLeftOperand()} which is type of {@link TExpression}.
4795     */
4796    /**
4797     * @deprecated As of v1.4.3.0, replaced by {@link EExpressionType#parenthesis_t}
4798     */
4799    public final static int compoundParenthesis = 18;
4800
4801    /**
4802     * unary plus expression,
4803     * <p>syntax: + expression
4804     * <p>expr can be accessed via {@link #getRightOperand()}
4805     */
4806    /**
4807     * @deprecated As of v1.4.3.0, replaced by {@link EExpressionType#unary_plus_t}
4808     */
4809    public final static int compoundUnaryPlus = 19;
4810
4811    /**
4812     * unary minus expression,
4813     * <p>syntax: - expression
4814     * <p>expr can be accessed via {@link #getRightOperand()}
4815     */
4816    /**
4817     * @deprecated As of v1.4.3.0, replaced by {@link EExpressionType#unary_minus_t}
4818     */
4819    public final static int compoundUnaryMinus = 20;
4820
4821    /**
4822     * Oracle prior expression, syntax: PRIOR expr
4823     * value can be accessed via {@link #getRightOperand()} which is type of {@link TExpression}
4824     */
4825    /**
4826     * @deprecated As of v1.4.3.0, replaced by {@link EExpressionType#unary_prior_t}
4827     */
4828    public final static int compoundPrior = 21;
4829
4830    /**
4831     * CASE expressions let you use IF ... THEN ... ELSE logic in SQL statements without
4832     * having to invoke procedures.
4833     * value can be accessed via {@link #getCaseExpression()} which is type of {@link TCaseExpression}.
4834     */
4835    /**
4836     * @deprecated As of v1.4.3.0, replaced by {@link EExpressionType#case_t}
4837     */
4838    public final static int caseExprOperator = 22;
4839
4840    /**
4841     * A CURSOR expression returns a nested cursor.
4842     * <p>syntax: CURSOR(subquery ),
4843     * <p>subquery can be accessed via {@link #getSubQuery()} which is type of {@link TSelectSqlStatement}.
4844     */
4845    /**
4846     * @deprecated As of v1.4.3.0, replaced by {@link EExpressionType#cursor_t}
4847     */
4848    public final static int cursorExprOperator = 23;
4849
4850    /**
4851     * funcation expression,
4852     * <p>value can be get via {@link #getFunctionCall()}
4853    */
4854    /**
4855     * @deprecated As of v1.4.3.0, replaced by {@link EExpressionType#function_t}
4856     */
4857    public final static int funcationCallOperator = 24;
4858
4859
4860    /**
4861     * datetime expression
4862     * <p>N/A
4863     */
4864    /**
4865     * @deprecated As of v1.4.3.0
4866     */
4867    public final static int datetimeExprOperator = 25;
4868
4869    /**
4870     * interval expression
4871     * <p>N/A
4872     */
4873    /**
4874     * @deprecated As of v1.4.3.0
4875     */
4876    public final static int intervalExprOperator = 26;
4877
4878
4879    /**
4880     * model expression, not implemented yet
4881     * <p>N/A
4882     */
4883    /**
4884     * @deprecated As of v1.4.3.0
4885     */
4886    public final static int modelExprOperator = 27;
4887
4888    /**
4889     * A scalar subquery expression is a subquery that returns exactly one column value
4890     * from one row.
4891     * <br>value can be get via {@link #getSubQuery()} which is type of {@link TSelectSqlStatement}.
4892     */
4893    /**
4894     * @deprecated As of v1.4.3.0, replaced by {@link EExpressionType#subquery_t}
4895     */
4896    public final static int subqueryExprOperator = 28;
4897
4898    //
4899    /**
4900     * type constructor expression,
4901     * <p>not implemented yet
4902     */
4903    /**
4904     * @deprecated As of v1.4.3.0
4905     */
4906    public final static int typeconstructorExprOperator = 29;
4907
4908
4909    /**
4910     * object access expression, some of those was represented by simpleObjectname expression.
4911     * <p>N/A
4912     */
4913    /**
4914     * @deprecated As of v1.4.3.0, replaced by {@link EExpressionType#object_access_t}
4915     */
4916    public final static int objectaccessExprOperator = 30;
4917
4918    // model conditions is not implemented yet
4919    // multiset conditions is not implemented yet
4920
4921    /**
4922     * pattern matching conditon support like only, regexp_like was treat as a function
4923     * <p>N/A
4924     */
4925    //public final static int patternMatchingExprOperator = 31;
4926    //xml conditon not implemented here, treat as a function
4927
4928
4929    /**
4930     * place holder expression
4931     */
4932    /**
4933     * @deprecated As of v1.4.3.0, replaced by {@link EExpressionType#place_holder_t}
4934     */
4935    public final static int placeholderExprOperator = 32;
4936
4937    /**
4938     * IN expr, values can be get via {@link #getInExpr()}
4939     */
4940    /**
4941     * @deprecated As of v1.4.3.0, replaced by {@link EExpressionType#group_t}
4942     */
4943    public final static int in_expr = 34;
4944
4945    /**
4946     * row descriptor, values can be get via {@link #getExprList()}
4947     */
4948    /**
4949     * @deprecated As of v1.4.3.0, replaced by {@link EExpressionType#list_t}
4950     */
4951    public final static int expr_list = 35;
4952
4953    // dummy expression operator, used in preOrderTraverse,inOrderTraverse, postOrderTraverse function only.
4954    /**
4955     * @deprecated As of v1.4.3.0
4956     */
4957    public final static int dummyOperator = 37;
4958
4959    /**
4960     * Comparison conditions compare one expression with another.
4961     * The result of such a comparison can be TRUE, FALSE, or NULL.
4962     *
4963     * A simple comparison condition specifies a comparison with expressions or subquery results.
4964     * <p>Syntax: expr EQUAL|NOT_EQUAL|LESS_THAN|GRREAT_THAN|LESS_EQUAL_THAN|GREATE_EQUAL_THAN expr,
4965     * or, (expr_list) EQUAL|NOT_EQUAL (subquery)
4966     * <p>expr can be accessed via {@link #getLeftOperand()} and {@link #getRightOperand()}
4967     */
4968    /**
4969     * @deprecated As of v1.4.3.0, replaced by {@link EExpressionType#simple_comparison_t}
4970     */
4971    public final static int simple_comparison_conditions = 40;
4972
4973    /**
4974     * Comparison conditions compare one expression with another.
4975     * The result of such a comparison can be TRUE, FALSE, or NULL.
4976     *
4977     * <p>A group comparison condition specifies a comparison with any or all members
4978     * in a list or subquery.
4979     * <p>Syntax: expr EQUAL|NOT_EQUAL|LESS_THAN|GRREAT_THAN|LESS_EQUAL_THAN|GREATE_EQUAL_THAN ANY|SOME|ALL (expr_list|subquery),
4980     * or, (expr_list) EQUAL|NOT_EQUAL ANY|SOME|ALL (expr_list|subquery)
4981     * <p>expr can be accessed via {@link #getLeftOperand()} and {@link #getRightOperand()}
4982     */
4983    /**
4984     * @deprecated As of v1.4.3.0, replaced by {@link EExpressionType#group_comparison_t}
4985     */
4986    public final static int group_comparison_conditions = 41;
4987
4988    /**
4989     * An in_condition is a membership condition. It tests a value for membership in a list of values or subquery.
4990     * <p>Syntax: (expr|expr_list) IN|NOT IN (expr_list|subquery).
4991     * <p>expr can be accessed via {@link #getLeftOperand()} and {@link #getRightOperand()}
4992     * <p>Use {@link #getOperatorToken()} to distinguish in or not in.
4993     */
4994    /**
4995     * @deprecated As of v1.4.3.0, replaced by {@link EExpressionType#in_t}
4996     */
4997    public final static int in_conditions = 42;
4998
4999    /**
5000     * The ORACLE floating-point conditions let you determine whether an expression is infinite or is the undefined result of an operation (is not a number or NaN).
5001     * <p>Syntax: expr IS|IS NOT (NAM|INFINITE).
5002     * <p>Value can be get via  {@link #getLeftOperand()}
5003     */
5004    /**
5005     * @deprecated As of v1.4.3.0, replaced by {@link EExpressionType#floating_point_t}
5006     */
5007    public final static int floating_point_conditions = 43;
5008
5009    /**
5010     * The pattern-matching conditions compare character data.
5011     * <p>The LIKE conditions specify a test involving pattern matching.
5012     * <p>Syntax: expr1 LIKE|NOT_LIKE expr1 [ESCAPE expr3],
5013     * <p>expr1 can be get via {@link #getLeftOperand()},
5014     * <p>expr2 can be get via  {@link #getRightOperand()},
5015     * <p>expr3 can be get via  {@link #getLikeEscapeOperand()},
5016     * <p>Use {@link #getOperatorToken()} to distinguish is like or is not like
5017     */
5018    /**
5019     * @deprecated As of v1.4.3.0, replaced by {@link EExpressionType#pattern_matching_t}
5020     */
5021    public final static int pattern_matching_conditions = 45;
5022
5023    /**
5024     * A NULL condition tests for nulls. This is the only condition that you should use to test for nulls.
5025     * <p>Syntax: expr IS [NOT] null
5026     * <p>expr can be accessed via {@link #getLeftOperand()}
5027     * <p>Use {@link #getOperatorToken()} to distinguish is null or is not null
5028     */
5029    /**
5030     * @deprecated As of v1.4.3.0, replaced by {@link EExpressionType#null_t}
5031     */
5032    public final static int null_conditions = 46;
5033
5034    /**
5035     * A BETWEEN condition determines whether the value of one expression is in an interval defined by two other expressions.
5036     * <p>Syntax: expr1 [NOT] BETWEEN expr2 AND expr3
5037     * <p>expr1 can be get via {@link #betweenOperand},
5038     * <p>expr2 can be get via {@link #getLeftOperand()}, and expr3 can be get via {@link #getRightOperand()},
5039     * <p>Use {@link #getOperatorToken()} to distinguish is between or is not between
5040     */
5041    /**
5042     * @deprecated As of v1.4.3.0, replaced by {@link EExpressionType#between_t}
5043     */
5044    public final static int between_conditions = 47;
5045
5046    /**
5047     * An EXISTS condition tests for existence of rows in a subquery.
5048     * <p>Syntax: EXISTS (subquery).
5049     * <p>value of subquery can be get via {@link #getSubQuery()}
5050     */
5051    /**
5052     * @deprecated As of v1.4.3.0, replaced by {@link EExpressionType#exists_t}
5053     */
5054    public final static int exists_condition = 48;
5055
5056    /**
5057     * <p>expr can be accessed via {@link #getLeftOperand()}
5058     */
5059    /**
5060     * @deprecated As of v1.4.3.0, replaced by {@link EExpressionType#is_of_type_t}
5061     */
5062    public final static int isoftype_condition = 49;
5063
5064    /**
5065     * A logical condition combines the results of two component conditions to produce a single result based on them or to invert the result of a single condition.
5066     *<p> Syntax: expr AND expr.
5067     * <p>expr can be accessed via {@link #getLeftOperand()} and {@link #getRightOperand()}
5068     */
5069    /**
5070     * @deprecated As of v1.4.3.0, replaced by {@link EExpressionType#logical_and_t}
5071     */
5072    public final static int logical_conditions_and = 50;
5073
5074    /**
5075     * A logical condition combines the results of two component conditions to produce a single result based on them or to invert the result of a single condition.
5076     * <p>Syntax: expr OR expr.
5077     * <p>expr can be accessed via {@link #getLeftOperand()} and {@link #getRightOperand()}
5078     */
5079    /**
5080     * @deprecated As of v1.4.3.0, replaced by {@link EExpressionType#logical_or_t}
5081     */
5082    public final static int logical_conditions_or = 51;
5083
5084    /**
5085     * A logical condition combines the results of two component conditions to produce a single result based on them or to invert the result of a single condition.
5086     * <p>Syntax: expr XOR expr.
5087     * <p>expr can be accessed via {@link #getLeftOperand()} and {@link #getRightOperand()}
5088     */
5089    /**
5090     * @deprecated As of v1.4.3.0, replaced by {@link EExpressionType#logical_xor_t}
5091     */
5092    public final static int logical_conditions_xor = 52;
5093
5094    /**
5095     * A logical condition combines the results of two component conditions to produce a single result based on them or to invert the result of a single condition.
5096     * <p>Syntax: NOT expr.
5097     * <p>value can be get via {@link #rightOperand},
5098     */
5099    /**
5100     * @deprecated As of v1.4.3.0, replaced by {@link EExpressionType#logical_not_t}
5101     */
5102    public final static int logical_conditions_not = 53;
5103
5104    /**
5105     * Mdx is logical condition
5106     */
5107    /**
5108     * @deprecated As of v1.4.3.0, replaced by {@link EExpressionType#is_t}
5109     */
5110    public final static int logical_conditions_is = 54;
5111
5112
5113    /**
5114     * Mdx range operator :
5115     */
5116    /**
5117     * @deprecated As of v1.4.3.0, replaced by {@link EExpressionType#range_t}
5118     */
5119    public final static int RANGE = 55;
5120
5121    /**
5122     *   mdx power operator ^
5123     */
5124    /**
5125     * @deprecated As of v1.4.3.0, replaced by {@link EExpressionType#power_t}
5126     */
5127    public final static int POWER = 56; //
5128
5129    /**
5130     * ORACLE,teradata date time expression, at time zone.
5131     * <p>Syntax: expr1 AT TIME ZONE expr2
5132     * <p>expr can be accessed via {@link #getLeftOperand()} and {@link #getRightOperand()}
5133     */
5134    /**
5135     * @deprecated As of v1.4.3.0, replaced by {@link EExpressionType#at_time_zone_t}
5136     */
5137    public final static int at_time_zone = 100;
5138
5139
5140    /**
5141     * ORACLE,teradata date time expression, at local.
5142     * <p>Syntax: expr AT LOCAL.
5143     * <p>expr can be accessed via {@link #getLeftOperand()}
5144     */
5145    /**
5146     * @deprecated As of v1.4.3.0, replaced by {@link EExpressionType#at_local_t}
5147     */
5148    public final static int at_local = 101;
5149
5150    /**
5151     * ORACLE date time expression, day to second.
5152     * <p>Syntax: expr DAY [( integer )] TO SECOND [( integer )].
5153     * <p>expr cam be get via {@link #getLeftOperand()}.
5154     * <p>The type of this operand is {@link TExpression}.
5155     */
5156    /**
5157     * @deprecated As of v1.4.3.0, replaced by {@link EExpressionType#day_to_second_t}
5158     */
5159    public final static int day_to_second = 102;
5160
5161    /**
5162     * ORACLE date time expression, year to month.
5163     *<p> Syntax: expr YEAR [( integer )] TO MONTH.
5164     * <p>expr can be accessed via {@link #getLeftOperand()}
5165     */
5166    /**
5167     * @deprecated As of v1.4.3.0, replaced by {@link EExpressionType#year_to_month_t}
5168     */
5169    public final static int year_to_month = 103;
5170
5171    /**
5172     * teradata interval expression:
5173     * <p>( date_time_expression date_time_term ) start TO end
5174     * <p>{@link #getIntervalExpr()}
5175     */
5176    /**
5177     * @deprecated As of v1.4.3.0, replaced by {@link EExpressionType#interval_t}
5178     */
5179    public final static int interval_expression = 104;
5180
5181    /**
5182     * teradata
5183     * Constructs a new instance of a structured type
5184     * and initializes it using the specified constructor method or function.
5185     *<p> object reference {@link TExpression#getFunctionCall()}
5186     */
5187    /**
5188     * @deprecated As of v1.4.3.0, replaced by {@link EExpressionType#new_structured_type_t}
5189     */
5190    public final static int new_structured_type = 110;
5191
5192    /**
5193     * teradata
5194     * Constructs a new instance of a dynamic or VARIANT_TYPE UDT
5195     * and defines the run time composition of the UDT.
5196     * object reference {@link #getNewVariantTypeArgumentList()}
5197     */
5198    /**
5199     * @deprecated As of v1.4.3.0, replaced by {@link EExpressionType#new_variant_type_t}
5200     */
5201    public final static int new_variant_type = 111;
5202
5203    /**
5204     * teradata period expression: ldiff
5205     * <p> expression can be accessed via {@link #getLeftOperand()} and {@link #getRightOperand()}
5206     */
5207    /**
5208     * @deprecated As of v1.4.3.0, replaced by {@link EExpressionType#period_ldiff_t}
5209     */
5210    public final static int period_ldiff = 115;
5211
5212    /**
5213     * teradata period expression: rdiff
5214     * <p> expression can be accessed via {@link #getLeftOperand()} and {@link #getRightOperand()}
5215     */
5216    /**
5217     * @deprecated As of v1.4.3.0, replaced by {@link EExpressionType#period_rdiff_t}
5218     */
5219    public final static int period_rdiff = 117;
5220
5221    /**
5222     * teradata period expression: p_intersect
5223     * <p> expression can be accessed via {@link #getLeftOperand()} and {@link #getRightOperand()}
5224     */
5225    /**
5226     * @deprecated As of v1.4.3.0, replaced by {@link EExpressionType#period_p_intersect_t}
5227     */
5228    public final static int period_p_intersect = 119;
5229
5230    /**
5231     * teradata period expression: p_normalize
5232     * <p> expression can be accessed via {@link #getLeftOperand()} and {@link #getRightOperand()}
5233     */
5234    /**
5235     * @deprecated As of v1.4.3.0, replaced by {@link EExpressionType#period_p_normalize_t}
5236     */
5237    public final static int period_p_normalize = 121;
5238
5239    /**
5240     * teradata until changed condition
5241     * <p> syntax: END(period_value_expression) IS[NOT] UNTIL_CHANGED
5242     * <p> ending bound of a Period value expression can be accessed via {@link #getLeftOperand()}
5243     */
5244    /**
5245     * @deprecated As of v1.4.3.0, replaced by {@link EExpressionType#until_changed_t}
5246     */
5247    public final static int until_changed = 123;
5248
5249    /**
5250     * Postgresql, is document condition
5251     * <p>expr is [not] document
5252     * <p> expr was set in {@link #leftOperand}.
5253     * <p> {@link #getOperatorToken()} can be used to check whether NOT keyword was used or not.
5254     */
5255    /**
5256     * @deprecated As of v1.4.3.0, replaced by {@link EExpressionType#is_document_t}
5257     */
5258    public final static int is_document = 133;
5259
5260
5261    /**
5262     * Postgresql,
5263     * <p>expr is [not] distinct from expr
5264     * <p>expr can be accessed via {@link #getLeftOperand()} and {@link #getRightOperand()}
5265     * <p> {@link #getOperatorToken()} can be used to check whether NOT keyword was used or not.
5266     */
5267    /**
5268     * @deprecated As of v1.4.3.0, replaced by {@link EExpressionType#is_distinct_from_t}
5269     */
5270    public final static int is_distinct_from = 135;
5271
5272    /**
5273     * Postgresql
5274     * <p> true, false, unknown condition
5275     * <p> expr is [not] true
5276     * <p> expr is [not] false
5277     * <p> expr is [not] unknown
5278     * <p> expr can be accessed via {@link #getLeftOperand()}
5279     * <p> {@link #getOperatorToken()} can be used to check whether NOT keyword was used or not.
5280     */
5281    /**
5282     * @deprecated As of v1.4.3.0, replaced by {@link EExpressionType#is_true_t},
5283     * {@link EExpressionType#is_false_t},{@link EExpressionType#is_unknown_t}
5284     */
5285    public final static int true_false_unknown = 137;
5286
5287
5288
5289    /**
5290     *  sql server, Is a clause that can be applied to a database definition or a column definition
5291     *  to define the collation, or to a character string expression to apply a collation cast.
5292     *
5293     * postgresql
5294     *
5295     *<p>expr can be accessed via {@link #getLeftOperand()} and {@link #getRightOperand()}
5296     */
5297    /**
5298     * @deprecated As of v1.4.3.0, replaced by {@link EExpressionType#collate_t}
5299     */
5300    public final static int COLLATE = 200+23;
5301
5302    /**
5303     * sql server, LEFTJOIN_OP *=
5304     * <p>expr can be accessed via {@link #getLeftOperand()} and {@link #getRightOperand()}
5305     */
5306    /**
5307     * @deprecated As of v1.4.3.0, replaced by {@link EExpressionType#left_join_t}
5308     */
5309    public final static int LEFTJOIN_OP = 200+24; //
5310
5311    /**
5312     * sql server, RIGHTJOIN_OP =*
5313     * <p>expr can be accessed via {@link #getLeftOperand()} and {@link #getRightOperand()}
5314     */
5315    /**
5316     * @deprecated As of v1.4.3.0, replaced by {@link EExpressionType#right_join_t}
5317     */
5318    public final static int RIGHTJOIN_OP = 200+25; //
5319
5320    /**
5321     * plsql RAISE_APPLICATION_ERROR (num=> -20107,    msg=> 'Duplicate customer or order ID');
5322     * <p>expr can be accessed via {@link #getLeftOperand()} and {@link #getRightOperand()}
5323     */
5324    /**
5325     * @deprecated As of v1.4.3.0, replaced by {@link EExpressionType#ref_arrow_t}
5326     */
5327    public final static int ref_arrow = 200+26;//
5328
5329
5330    /**
5331     * plsql
5332     * <p>expr can be accessed via {@link #getLeftOperand()}
5333     */
5334    /**
5335     * @deprecated As of v1.4.3.0, replaced by {@link EExpressionType#typecast_t}
5336     */
5337    public final static int typecast = 200+27;//
5338    /**
5339     * @deprecated As of v1.4.3.0, replaced by {@link EExpressionType#arrayaccess_t}
5340     */
5341    public final static int arrayaccess = 200+28;//plsql array access
5342
5343    /**
5344     * oracle unary operator connect_by_root is only valid in hierarchical queries
5345     * <p>expr can be accessed via {@link #getRightOperand()}
5346     */
5347    /**
5348     * @deprecated As of v1.4.3.0, replaced by {@link EExpressionType#unary_connect_by_root_t}
5349     */
5350    public final static int connect_by_root = 200+29; //
5351
5352    /**
5353     * SQL SERVER Proprietary syntax, set alias of a column in select list,
5354     * column expr in rightOperand.
5355     * <p>expr can be accessed via {@link #getLeftOperand()} and {@link #getRightOperand()}
5356     */
5357    /**
5358     * @deprecated As of v1.4.3.0, replaced by {@link EExpressionType#sqlserver_proprietary_column_alias_t}
5359     */
5360    public final static int sqlserver_proprietary_column_alias = 200+30; //
5361
5362
5363    /**
5364      MySQL binary operator, select binary 'a' = 'A'
5365     * <p>syntax: binary expr
5366     * <p>expr can be accessed via {@link #getRightOperand()}
5367     */
5368    /**
5369     * @deprecated As of v1.4.3.0, replaced by {@link EExpressionType#unary_binary_operator_t}
5370     */
5371    public final static int mysql_binary_operator = 300;
5372
5373    /**
5374     * MySQL left shift
5375     * <p>Syntax: expr << expr.
5376     * <p>expr can be accessed via {@link #getLeftOperand()} and {@link #getRightOperand()}
5377     */
5378    /**
5379     * @deprecated As of v1.4.3.0, replaced by {@link EExpressionType#left_shift_t}
5380     */
5381    public final static int left_shift = 301;
5382
5383    /**
5384     * MySQL rigth shift
5385     * <p>Syntax: expr >> expr.
5386     * <p>expr can be accessed via {@link #getLeftOperand()} and {@link #getRightOperand()}
5387     */
5388    /**
5389     * @deprecated As of v1.4.3.0, replaced by {@link EExpressionType#right_shift_t}
5390     */
5391    public final static int right_shift = 302;
5392
5393    /**
5394     * Oracle MULTISET operator
5395     * <p>Syntax MULTISET (subquery)
5396     * <p> subquery can be get via {@link #getSubQuery()}
5397     */
5398    /**
5399     * @deprecated As of v1.4.3.0, replaced by {@link EExpressionType#multiset_t}
5400     */
5401    public final static int multisetExprOperator = 310;
5402
5403    /**
5404     * If an expression yields a value of a composite type (row type), then a specific field of the row can be extracted by writing
5405     * <p> expression.fieldname
5406     * <p> In general the row expression must be parenthesized, but the parentheses can be omitted
5407     * <p> when the expression to be selected from is just a table reference or positional parameter.
5408     * <p> For example:
5409     * <p> mytable.mycolumn
5410     * <p> $1.somecolumn
5411     * <p> (rowfunction(a,b)).col3
5412     * <p>
5413     * <p> (Thus, a qualified column reference is actually just a special case of the field selection syntax.) An important special case is extracting a field from a table column that is of a composite type:
5414     * <p> (compositecol).somefield
5415     * <p> (mytable.compositecol).somefield
5416     * <p> The parentheses are required here to show that compositecol is a column name not a table name,
5417     * <p> or that mytable is a table name not a schema name in the second case.
5418     * <p>
5419     * <p> n a select list, you can ask for all fields of a composite value by writing .*:
5420     * <p> (compositecol).*
5421     * <p>
5422     * <p>
5423     * <p> When expression in following syntax, it will be marked as {@link #fieldSelection}, and check {@link #getFieldName()}
5424     * <p> (rowfunction(a,b)).col3
5425     * <p> (compositecol).somefield
5426     * <p> (mytable.compositecol).somefield
5427     * <p> (compositecol).*
5428     * <p>
5429     * <p> Otherwise, it will be marked as {@link #simpleObjectname}:
5430     * <p> mytable.mycolumn
5431     * <p> $1.somecolumn
5432     */
5433    /**
5434     * @deprecated As of v1.4.3.0, replaced by {@link EExpressionType#fieldselection_t}
5435     */
5436    public final static int fieldSelection = 501;
5437
5438    /**
5439     * An array constructor is an expression that builds an array value using values for its member elements.
5440     * <p> like this: ARRAY[1,2,3+4]
5441     * <p> array element values can be accessed via {@link #getExprList()},
5442     * <p> or {@link #getExprList()} can be null when it is: array[]
5443     * <p>
5444     * <p> It is also possible to construct an array from the results of a subquery like this:
5445     * <p> SELECT ARRAY(SELECT oid FROM pg_proc WHERE proname LIKE 'bytea%');
5446     * <p> thus, subquery can be access via {@link #getSubQuery()}
5447     */
5448    /**
5449     * @deprecated As of v1.4.3.0, replaced by {@link EExpressionType#array_constructor_t}
5450     */
5451    public final static int arrayConstructor = 505;     //postgresql
5452
5453    /**
5454     * A row constructor is an expression that builds a row value (also called a composite value) using values for its member fields.
5455     * <p> like this: ROW(1,2.5,'this is a test')
5456     * <p> element values can be accessed via {@link #getExprList()},
5457     * <p> or {@link #getExprList()} can be null when it is: row()
5458     */
5459    /**
5460     * @deprecated As of v1.4.3.0, replaced by {@link EExpressionType#row_constructor_t}
5461     */
5462    public final static int rowConstructor = 509;
5463
5464    /**
5465     * Postgresql factorial:
5466     * <p> expr !
5467     * <p> expr can be accessed via {@link #getLeftOperand()}
5468     */
5469    /**
5470     * @deprecated As of v1.4.3.0, replaced by {@link EExpressionType#unary_factorial_t}
5471     */
5472    public final static int factorial = 515;
5473
5474    /**
5475     * Postgresql square root
5476     * <p> |/ 25.0
5477     * <p> expr can be accessed via {@link #getRightOperand()}
5478     */
5479    /**
5480     * @deprecated As of v1.4.3.0, replaced by {@link EExpressionType#unary_squareroot_t}
5481     */
5482    public final static int squareRoot = 517;
5483
5484    /**
5485     * Postgresql cube root
5486     * <p> ||/ 27.0
5487     * <p> expr can be accessed via {@link #getRightOperand()}
5488     */
5489    /**
5490     * @deprecated As of v1.4.3.0, replaced by {@link EExpressionType#unary_cuberoot_t}
5491     */
5492    public final static int cubeRoot = 519;
5493
5494    /**
5495     * Postgresql factorial (prefix operator):
5496     * <p> !! 5
5497     * <p> expr can be accessed via {@link #getRightOperand()}
5498     */
5499    /**
5500     * @deprecated As of v1.4.3.0, replaced by {@link EExpressionType#unary_factorialprefix_t}
5501     */
5502    public final static int factorialPrefix = 521;
5503
5504    /**
5505     * Postgresql absolute value
5506     * <p> @ -5.0
5507     * <p> expr can be accessed via {@link #getRightOperand()}
5508     */
5509    /**
5510     * @deprecated As of v1.4.3.0, replaced by {@link EExpressionType#unary_absolutevalue_t}
5511     */
5512    public final static int absoluteValue = 523;
5513
5514    /**
5515     * Postgresql bitwise shit left
5516     * <p> expr << expr
5517     * <p> expr can be accessed via {@link #getLeftOperand()} and {@link #getRightOperand()}
5518     */
5519    /**
5520     * @deprecated As of v1.4.3.0, replaced by {@link EExpressionType#bitwise_shift_left_t}
5521     */
5522    public final static int BITWISE_SHIFT_LEFT = 525; //postgresql
5523
5524    /**
5525     * Postgresql bitwise shit right
5526     * <p> expr >> expr
5527     * <p> expr can be accessed via {@link #getLeftOperand()} and {@link #getRightOperand()}
5528     */
5529    /**
5530     * @deprecated As of v1.4.3.0, replaced by {@link EExpressionType#bitwise_shift_right_t}
5531     */
5532    public final static int BITWISE_SHIFT_RIGHT = 527; //postgresql
5533
5534    /**
5535     * Postgresql bitwise not
5536     * <p> ~expr
5537     * <p> expr can be accessed via {@link #getRightOperand()}
5538     */
5539    /**
5540     * @deprecated As of v1.4.3.0, replaced by {@link EExpressionType#unary_bitwise_not_t}
5541     */
5542    public final static int BITWISE_NOT = 529; //postgresql
5543
5544    /**
5545     * sql server
5546     * <p>expr can be accessed via {@link #getRightOperand()}
5547     */
5548
5549    /**
5550     * @deprecated As of v1.4.3.0, replaced by {@link EExpressionType#unary_bitwise_not_t}
5551     */
5552    public final static int compoundUnaryBitwiseNot = 200+22; //
5553
5554    //
5555
5556    /**
5557     * ORACLE
5558     * <p>expr can be accessed via {@link #getLeftOperand()} and {@link #getRightOperand()}
5559     */
5560    /**
5561     * @deprecated As of v1.4.3.0, replaced by {@link EExpressionType#member_of_t}
5562     */
5563    public final static int member_of = 541;
5564
5565    /**
5566     * Netezza
5567     * <p>NEXT VALUE FOR <sequence name>
5568     * <p>NEXT <integer expression> VALUE FOR <sequence name>
5569     * <p> integer expression can be accessed via {@link #getLeftOperand()} if any.
5570     * <p> sequence name name can be accessed via {@link #getRightOperand()}
5571     */
5572
5573    /**
5574     * @deprecated As of v1.4.3.0, replaced by {@link EExpressionType#next_value_for_t}
5575     */
5576    public final static int nextValueOf = 601;
5577
5578    /**
5579     * This UnknownOperator means this expression was not recognized by SQL parser yet.
5580     * <p>In syntax like this:
5581     * <p> expr OPERATOR expr
5582     * <p>expr can be accessed via {@link #getLeftOperand()} and {@link #getRightOperand()}
5583     */
5584    /**
5585     * @deprecated As of v1.4.3.0, replaced by {@link EExpressionType#unknown_t}
5586     */
5587    public final static int UnknownOperator = 901;
5588
5589
5590    /**
5591     * This UnknownLeftUnaryOperator means this expression was not recognized by SQL parser yet.
5592     * <p>In syntax like this:
5593     * <p> OPERATOR expr
5594     * <p>expr can be accessed via {@link #getRightOperand()}
5595     */
5596    /**
5597     * @deprecated As of v1.4.3.0, replaced by {@link EExpressionType#unary_left_unknown_t}
5598     */
5599    public final static int UnknownUnaryOperator = 905;
5600
5601    /**
5602     * This UnknownLeftUnaryOperator means this expression was not recognized by SQL parser yet.
5603     * <p>In syntax like this:
5604     * <p> expr OPERATOR
5605     * <p>expr can be accessed via {@link #getLeftOperand()}
5606     */
5607    /**
5608     * @deprecated As of v1.4.3.0, replaced by {@link EExpressionType#unary_right_unknown_t}
5609     */
5610    public final static int UnknownUnaryOperatorRight = 909;
5611
5612
5613}