001package gudusoft.gsqlparser.nodes;
002
003import gudusoft.gsqlparser.*;
004import gudusoft.gsqlparser.nodes.mysql.TGroupConcatParam;
005import gudusoft.gsqlparser.nodes.oracle.TListaggOverflow;
006import gudusoft.gsqlparser.nodes.teradata.TDataConversionItem;
007import gudusoft.gsqlparser.sqlenv.ESQLDataObjectType;
008import gudusoft.gsqlparser.sqlenv.TSQLEnv;
009import gudusoft.gsqlparser.sqlenv.TSQLFunction;
010import gudusoft.gsqlparser.util.CollectionUtil;
011import gudusoft.gsqlparser.util.SQLUtil;
012import gudusoft.gsqlparser.util.functionChecker;
013
014import java.io.BufferedReader;
015import java.io.IOException;
016import java.io.InputStreamReader;
017import java.util.*;
018
019
020/**
021 * Represents the database function, all functions are represented by this class no matter what's type of the function.
022 * Maybe it's a better idea to create the specific sub-class for function with different syntax such as the built-in
023 * function extract, convert, substring and others. We may implement this feature in the later version.
024 *
025 * For the most of functions, the arguments are a lists of {@link gudusoft.gsqlparser.nodes.TExpression}. For other
026 * functions with the different syntax in arguments, please check the detailed information below.
027 *
028 * this class includes function name and arguments.
029 * <br>There are 3 types of functions:
030 * <ul>
031 *     <li>Arguments is a list of expressions</li>
032 *     <li>Analytic function</li>
033 *     <li>Function with specific arguments, such as cast function</li>
034 * </ul>
035 *
036 *
037 *     <b>1.Arguments is a list of expressions</b>
038 *     <br>
039* function([expr,expr, ...])
040 * <ul>
041 *     <li>function name: {@link #getFunctionName()}</li>
042 *     <li>args: {@link #getArgs()}</li>
043 *     </ul>
044 * <p>
045 *
046 *     <b>2.Analytic function</b>
047 *     <br>
048 *  Use {@link #getWindowDef()} to get over clause information.
049* <p>
050 *     <b>3.Function with specific arguments</b>
051* <p><b>trim</b>
052 * <ul>
053 *     <li>type: {@link EFunctionType#trim_t}</li>
054 *     <li>arg: {@link #getTrimArgument()}</li>
055 * </ul>
056* <p><b>cast(expr as typename)</b>,
057 * <b>cast(expr as typename [,datatypeAttribute])</b>,
058 * <b>cast(expr as datatypeAttribute)</b>
059 * <ul>
060 *     <li>type:{@link EFunctionType#cast_t}</li>
061 *     <li>expr: {@link #getExpr1()}</li>
062 *     <li>typename: {@link #getTypename()}, datatypeAttribute is included in {@link TTypeName} as well</li>
063 * </ul>
064*
065*
066* <p><b>convert(typename,[null|not null] expr1 [,expr2])</b>,
067 * <ul>
068 *     <li>type: {@link EFunctionType#convert_t}</li>
069 *     <li>expr1: {@link #getExpr1()}</li>
070 *     <li>expr2: {@link #getExpr2()}</li>
071 *     <li>typename: {@link #getTypename()}</li>
072 * </ul>
073*
074* <p><b>extract([time_token from expr])</b>,
075 * <ul>
076 *     <li>type: {@link EFunctionType#extract_t}</li>
077 *     <li>expr: {@link #getExpr1()}</li>
078 *     <li>time_token: {@link #getExtract_time_token()}</li>
079 * </ul>
080*
081* <p>sql server contains function,<b>contains(in_expr, expr [,langTerm])</b>,
082 * <ul>
083 *     <li>type: {@link EFunctionType#contains_t}</li>
084 *     <li>expr: {@link #getExpr1()}</li>
085 *     <li>in_expr: {@link #getInExpr()}</li>
086 * </ul>
087*
088*
089* <p>sql server freetext,freetext(contain in expr, expr [,langTerm])</p>,
090 * <ul>
091 *     <li>type: {@link EFunctionType#freetext_t}</li>
092 *     <li>expr: {@link #getExpr1()}</li>
093 *     <li>in_expr: {@link #getInExpr()}</li>
094 * </ul>
095*
096 *
097* <p>Oracle Extract(XML): <b>extract(XMLType_instance, XPath_string[,namespace_string])</b>,
098 * <ul>
099 *     <li>type: {@link EFunctionType#extractxml_t}</li>
100 *     <li>XMLType_instance: {@link #getXMLType_Instance()}</li>
101 *     <li>XPath_string: {@link #getXPath_String()}</li>
102 *     <li>namespace_string: {@link #getNamespace_String()}</li>
103 * </ul>
104
105* <p> <b>Rank(value,...)</b>,
106 * <ul>
107 *     <li>type: {@link EFunctionType#rank_t}</li>
108 *     <li>value list {@link #getOrderByList()}</li>
109 * </ul>
110 *
111 * <p>XMLPassingClause of XMLExists function</p>
112 * <ul>
113 *     <li>type: {@link EFunctionType#xmlexists_t}</li>
114 *     <li>value list {@link #getPassingClause()}</li>
115 * </ul>
116 *
117*/
118public class TFunctionCall extends TParseTreeNode{
119
120    protected TExpression filterClause;
121
122    /**
123     * spark sql filter clause, postgresql filter clause
124     * 
125     * <pre>
126     * SELECT COUNT(*) FILTER (WHERE bid_amount_value < 10000) AS low_range_bid_count_value FROM A
127     * </pre>
128     * 
129     * @return
130     */
131    public TExpression getFilterClause() {
132        return filterClause;
133    }
134
135    public void setFilterClause(TWhereClause filterClause) {
136        if (filterClause == null) return;
137        this.filterClause = filterClause.getCondition();
138    }
139
140    public void setFilterClause(TDummy filterClause) {
141        if (filterClause == null) return;
142        this.setFilterClause((TWhereClause)filterClause.node1);
143    }      
144 
145
146    private  TIndirection indirection;
147
148    public void setIndirection(TIndirection indirection) {
149        this.indirection = indirection;
150    }
151
152    /**
153     * databricks,  current_version().dbsql_version;
154     * @return
155     */
156    public TIndirection getIndirection() {
157        return indirection;
158    }
159
160
161        final static Map<EDbVendor, Map<String, Set<String>>> tableFunctionMap = new HashMap<EDbVendor, Map<String, Set<String>>>();
162        static {
163                tableFunctionMap.put(EDbVendor.dbvmssql, loadTableFunctions(EDbVendor.dbvmssql));
164        tableFunctionMap.put(EDbVendor.dbvoracle, loadTableFunctions(EDbVendor.dbvoracle));
165        }
166        
167        private static Map<String, Set<String>> loadTableFunctions(EDbVendor vendor) {
168                Map<String, Set<String>> tableFunctionInfoMap = new HashMap<String, Set<String>>();
169                try {
170                        BufferedReader reader = new BufferedReader(new InputStreamReader(TFunctionCall.class.getResourceAsStream(
171                                        "/gudusoft/gsqlparser/tablefunction/" + vendor.name().replace("dbv", "") + ".txt")));
172                        String line;
173                        while ((line = reader.readLine()) != null) {
174                                String[] tableFunctionInfo = line.toUpperCase().split("\\s*,\\s*");
175                                if (tableFunctionInfo.length > 1) {
176                                        tableFunctionInfoMap.put(tableFunctionInfo[0],
177                                                        CollectionUtil.convertArraysToSet(tableFunctionInfo));
178                                        tableFunctionInfoMap.get(tableFunctionInfo[0]).remove(tableFunctionInfo[0]);
179                                }
180                        }
181                } catch (IOException e) {
182                        e.printStackTrace();
183                }
184                return tableFunctionInfoMap;
185        }
186
187        private ArrayList<TDataConversionItem> dataConversionItems;
188
189    public void setDataConversionItems(ArrayList<TDataConversionItem> dataConversionItems) {
190        this.dataConversionItems = dataConversionItems;
191    }
192
193    public ArrayList<TDataConversionItem> getDataConversionItems() {
194        return dataConversionItems;
195    }
196
197    private TListaggOverflow listaggOverflow;
198
199    public void setListaggOverflow(TListaggOverflow listaggOverflow) {
200        this.listaggOverflow = listaggOverflow;
201    }
202
203    public TListaggOverflow getListaggOverflow() {
204        return listaggOverflow;
205    }
206
207    public void setFirstArgAsDateTimePart(int pos){
208            if (this.getArgs() == null) return;
209            if (this.getArgs().size()<=pos) return;
210            TExpression expression = this.getArgs().getExpression(pos);
211            if (expression.getObjectOperand() != null){
212                expression.getObjectOperand().setDbObjectType(EDbObjectType.date_time_part);
213        }
214    }
215        public int isColumnInThisTableFunction(TSQLEnv sqlEnv, EDbVendor dbVendor, TObjectName pColumn) {
216                int ret = TBaseType.COLUMN_IN_TABEL_FUNCTION_NOTSURE;
217                String functionNameKey = this.getFunctionName().toString().toUpperCase();
218                functionNameKey = functionNameKey.substring(functionNameKey.lastIndexOf('.') + 1);
219                Map<String, Set<String>> tableFunctionInfoMap = tableFunctionMap.get(dbVendor);
220                if (tableFunctionInfoMap != null && tableFunctionInfoMap.containsKey(functionNameKey)) {
221                        if (tableFunctionInfoMap.get(functionNameKey).contains(SQLUtil.getIdentifierNormalName(dbVendor, pColumn.getColumnNameOnly(), ESQLDataObjectType.dotColumn).toUpperCase())) {
222                                ret = TBaseType.COLUMN_IN_TABEL_FUNCTION_YES;
223                        } else {
224                                ret = TBaseType.COLUMN_IN_TABEL_FUNCTION_NO;
225                        }
226                }
227                else if(this.functionType == EFunctionType.udf_t && sqlEnv!=null && sqlEnv.searchFunction(this.getFunctionName().toString())!=null){
228                        TSQLFunction functionDef = sqlEnv.searchFunction(this.getFunctionName().toString());
229                        if(functionDef.searchColumnInReturnTable(pColumn.getColumnNameOnly())){
230                                ret = TBaseType.COLUMN_IN_TABEL_FUNCTION_YES;
231                        }
232                        else {
233                                ret = TBaseType.COLUMN_IN_TABEL_FUNCTION_NO;
234                        }
235                }
236                else {
237                        ret = TBaseType.COLUMN_IN_TABEL_FUNCTION_NOTSURE;
238                }
239
240                return ret;
241        }
242
243         protected TWithinGroup withinGroup;
244
245    public void setWithinGroup(TWithinGroup withinGroup) {
246        this.withinGroup = withinGroup;
247    }
248
249    public TWithinGroup getWithinGroup() {
250        return withinGroup;
251    }
252
253    public void setIntervalUnit(String intervalUnit) {
254        this.intervalUnit = intervalUnit;
255    }
256
257    public String getIntervalUnit() {
258        return intervalUnit;
259
260    }
261
262    private String intervalUnit;
263
264    private  TExpression stringExpr;
265
266    public void setStringExpr(TExpression stringExpr) {
267        this.stringExpr = stringExpr;
268    }
269
270    /**
271     * DB2 listagg function
272     * @return the first argument of the listagg function
273     */
274    public TExpression getStringExpr() {
275        return stringExpr;
276    }
277
278    private TExpression separatorExpr;
279
280    public void setSeparatorExpr(TExpression separatorExpr) {
281        this.separatorExpr = separatorExpr;
282    }
283
284    /**
285     * DB2 listagg function.
286     * @return the second argument of the listagg function.
287     */
288    public TExpression getSeparatorExpr() {
289
290        return separatorExpr;
291    }
292
293    private TExpression searchCondition;
294
295    /**
296     * contains search condition. or freetext_string in freetext predicate
297     *
298     * @param searchCondition contains search condition.
299     */
300    public void setSearchCondition(TExpression searchCondition) {
301        this.searchCondition = searchCondition;
302    }
303
304    /**
305     * contains search condition. It usually a string constant or a variable.
306     * SQL Server contains predicate.
307     * <pre>
308     * CONTAINS (
309     * {
310     * column_name | ( column_list )
311     * | *
312     * | PROPERTY ( { column_name }, 'property_name' )
313     * }
314     * , '&lt;contains_search_condition&gt;'
315     * [ , LANGUAGE language_term ]
316     * )
317     *</pre>
318     *
319     * Or freetext_string in freetext predicate
320     * <pre>
321     *     FREETEXT ( { column_name | (column_list) | * }
322     *     , 'freetext_string' [ , LANGUAGE language_term ] )
323     * </pre>
324     *
325     * @return contains search condition
326     */
327    public TExpression getSearchCondition() {
328
329        return searchCondition;
330    }
331
332    private TExpression columnNameOrListExpression;
333
334    /**
335     * set column name or column list of SQL Server contains predicate or freetext predicate
336     *
337     * @param columnNameOrListExpression column name or column list
338     * @see #getColumnNameOrListExpression
339     */
340    public void setColumnNameOrListExpression(TExpression columnNameOrListExpression) {
341        this.columnNameOrListExpression = columnNameOrListExpression;
342    }
343
344    /**
345     * get column name or column list in SQL Server contains predicate.
346     * <pre>
347     * CONTAINS (
348     * {
349     * column_name | ( column_list )
350     * | *
351     * | PROPERTY ( { column_name }, 'property_name' )
352     * }
353     * , '&lt;contains_search_condition&gt;'
354     * [ , LANGUAGE language_term ]
355     * )
356     *</pre>
357     * Or column name or column list in freetext predicate
358     * <pre>
359     *     FREETEXT ( { column_name | (column_list) | * }
360     *     , 'freetext_string' [ , LANGUAGE language_term ] )
361     * </pre>
362     *
363     * If this expression represents a column name, then the type of this expression is {@link gudusoft.gsqlparser.EExpressionType#simple_object_name_t},
364     * if this expression represents a column list, then the type of this expression is {@link gudusoft.gsqlparser.EExpressionType#list_t},
365     *
366     *
367     * @return column name or column list
368     */
369    public TExpression getColumnNameOrListExpression() {
370
371        return columnNameOrListExpression;
372    }
373
374    private TExpression startExpression;
375    private TExpression lengthExpression;
376
377    /**
378     * set a start expression that specifies the position within {@link #getSourceExpression} that is to be the first
379     * string unit of the result in substring function.
380     * <pre>
381     *     substring(sourceExpression from startExpression [for lengthExpression])
382     *     substring(sourceExpression , startExpression [, lengthExpression])
383     * </pre>
384     *
385     * @param startExpression an expression that specifies the position within {@link #getSourceExpression}
386     * that is to be the first string unit of the result in substring function
387     * @see #getStartExpression
388     */
389    public void setStartExpression(TExpression startExpression) {
390        this.startExpression = startExpression;
391    }
392
393    /**
394     * set the length expression in substring function.
395     * <pre>
396     *     substring(sourceExpression from startExpression [for lengthExpression])
397     *     substring(sourceExpression , startExpression [, lengthExpression])
398     * </pre>
399     *
400     * @param lengthExpression the length expression in substring function.
401     * @see #getLengthExpression
402     */
403    public void setLengthExpression(TExpression lengthExpression) {
404        this.lengthExpression = lengthExpression;
405    }
406
407    /**
408     * A start expression that specifies the position within {@link #getSourceExpression} that is to be the first
409     * string unit of the result in substring function.
410     * <p>substring</p>
411     * <pre>
412     *     substring(sourceExpression from startExpression [for lengthExpression])
413     *     substring(sourceExpression , startExpression [, lengthExpression])
414     * </pre>
415     *
416     * @return an expression that specifies the position within {@link #getSourceExpression} that is to be the first
417     * string unit of the result.
418     */
419    public TExpression getStartExpression() {
420
421        return startExpression;
422    }
423
424    /**
425     * The length of the {@link #getSourceExpression} string unit to be returned in substring function.
426     * <p>substring</p>
427     * <pre>
428     *     substring(sourceExpression from startExpression [for lengthExpression])
429     *     substring(sourceExpression , startExpression [, lengthExpression])
430     * </pre>
431     *
432     * @return the length of the string unit to be returned.
433     */
434    public TExpression getLengthExpression() {
435        return lengthExpression;
436    }
437
438    private TExpression sourceExpression;
439
440    /**
441     * set an expression that specifies the string from which the result is derived in substring function.
442     * <pre>
443     *     substring(sourceExpression from startExpression [for lengthExpression])
444     *     substring(sourceExpression , startExpression [, lengthExpression])
445     * </pre>
446     *
447     * @param sourceExpression An expression that specifies the string from which the result is derived
448     * @see #getSourceExpression
449     */
450    public void setSourceExpression(TExpression sourceExpression) {
451        this.sourceExpression = sourceExpression;
452    }
453
454    /**
455     * An expression that specifies the string from which the result is derived in substring function.
456     * <p>substring: DB2</p>
457     * <pre>
458     *     substring(sourceExpression from startExpression [for lengthExpression])
459     *     substring(sourceExpression , startExpression [, lengthExpression])
460     * </pre>
461     *
462     * @return An expression that specifies the string from which the result is derived
463     */
464    public TExpression getSourceExpression() {
465
466        return sourceExpression;
467    }
468
469    private TExpression typeExpression;
470
471    /**
472     * a structured type expression in DB2 subtype-treatment: treat.
473     *
474     * @param typeExpression a structured type expression
475     * @see #getTypeExpression
476     */
477    public void setTypeExpression(TExpression typeExpression) {
478        this.typeExpression = typeExpression;
479    }
480
481    /**
482     * A structured type expression in subtype-treatment.
483     * <p>treat function: DB2, Greenplum</p>
484     *
485     * @return a structured type expression
486     */
487    public TExpression getTypeExpression() {
488
489        return typeExpression;
490    }
491
492    private TExpression castOperand;
493
494    /**
495     * cast specification, set the first operand in the cast specification
496     *
497     * @param castOperand set the first operand in the cast specification
498     * @see #getCastOperand
499     */
500    public void setCastOperand(TExpression castOperand) {
501        this.castOperand = castOperand;
502    }
503
504    /**
505     * The first operand in the cast specification.
506     * <p>cast specification: DB2, Greenplum,SQL Server; try_cast function of SQL Server</p>
507     *
508     * @return The first operand in the cast specification
509     */
510    public TExpression getCastOperand() {
511
512        return castOperand;
513    }
514
515    private TExpression dateExpression;
516
517    /**
518     * set date, time or timestamp expression in extract/extend function.
519     *
520     * @param dateExpression date, time or timestamp expression
521     * @see #getDateExpression
522     */
523    public void setDateExpression(TExpression dateExpression) {
524        this.dateExpression = dateExpression;
525    }
526
527    /**
528     * date, time or timestamp expression in extract function of DB2, Greenplum.
529     * <p>
530     *     datetime or date value expression in extend function of informix.
531     * </p>
532     *
533     * @return date, time or timestamp expression
534     */
535    public TExpression getDateExpression() {
536        return dateExpression;
537    }
538
539    private TExpressionCallTarget callTarget;
540
541    /**
542     * set expressionCallTarget
543     *
544     * @param callTarget expression call target
545     * @see #getCallTarget
546     */
547    public void setCallTarget(TExpressionCallTarget callTarget) {
548        this.callTarget = callTarget;
549    }
550
551    /**
552     * get an xml type column, parameter, variable or subquery.
553     * <pre>
554     *     DECLARE @myDoc xml
555     *      DECLARE @ProdID int
556     *      SET @myDoc = '&lt;Root&gt;
557     *     &lt;ProductDescription ProductID="1" ProductName="Road Bike"&gt;
558     *     &lt;Features&gt;
559     *     &lt;Warranty&gt;1 year parts and labor &lt;/Warranty&gt;
560     *     &lt;Maintenance&gt;3 year parts and labor extended maintenance is available &lt;/Maintenance&gt;
561     *     &lt;/Features&gt;
562     *     &lt;/ProductDescription&gt;
563     *     &lt;/Root&gt;'
564     *     SET @ProdID =  @myDoc.value('(/Root/ProductDescription/@ProductID)[1]', 'int' )
565     *     SELECT @ProdID
566     * </pre>
567     *
568     * the value returned by this method represents <code>@myDoc</code> before the value() function.
569     *
570     * SQL Server value() Method performs an XQuery against the XML and returns a value of SQL type.
571     * <p></p>
572     * You typically use this method to extract a value from an XML instance stored in an xml type
573     * column, parameter, or variable.
574     *
575     * @return expressionCallTarget that represents an xml type column, parameter, variable or subquery
576     */
577    public TExpressionCallTarget getCallTarget() {
578
579        return callTarget;
580    }
581
582    private TGroupConcatParam groupConcatParam;
583
584    public void setGroupConcatParam(TGroupConcatParam groupConcatParam) {
585        this.groupConcatParam = groupConcatParam;
586    }
587
588    public TGroupConcatParam getGroupConcatParam() {
589
590        return groupConcatParam;
591    }
592
593    public static boolean isBuiltIn(String pName, EDbVendor pDBVendor){
594        List<String> avVersions = functionChecker.getAvailableDbVersions(pDBVendor);
595        return functionChecker.isBuiltInFunction(pName,pDBVendor,avVersions.get(avVersions.size()-1));
596    }
597
598    private boolean isCheckedBuiltIn = false;
599    private boolean isBuiltIn = false;
600
601    public boolean isBuiltIn(EDbVendor pDBVendor) {
602        if (isCheckedBuiltIn) return isBuiltIn;
603        List<String> avVersions = functionChecker.getAvailableDbVersions(pDBVendor);
604        isBuiltIn = functionChecker.isBuiltInFunction(this.functionName.toString(),pDBVendor,avVersions.get(avVersions.size()-1));
605        isCheckedBuiltIn = true;
606        return isBuiltIn;
607    }
608
609    private TXMLPassingClause passingClause;
610
611    public void setPassingClause(TXMLPassingClause passingClause) {
612        this.passingClause = passingClause;
613    }
614
615    /**
616     *  XMLPassingClause of XMLExists function
617     * @return XMLPassingClause of XMLExists function
618     */
619    public TXMLPassingClause getPassingClause() {
620        return passingClause;
621    }
622
623    private EAggregateType aggregateType = EAggregateType.none;
624
625    /**
626     * set <code>ALL | DISTINCT | UNIQUE</code> keywords used in an aggregate function.
627     *
628     * @param aggregateType
629     * @see #getAggregateType
630     */
631    public void setAggregateType(EAggregateType aggregateType) {
632        this.aggregateType = aggregateType;
633    }
634
635    /**
636     * get <code>ALL | DISTINCT | UNIQUE</code> keywords used in an aggregate function.
637     * An aggregate function performs a calculation on a set of values, and returns a single value.
638     *
639     * @return aggregate type, one of those values:  none,all,distinct,unique
640     */
641    public EAggregateType getAggregateType() {
642
643        return aggregateType;
644    }
645
646    private  TOrderByItemList orderByList;
647
648    public void setOrderByList(TOrderByItemList orderByList) {
649        this.orderByList = orderByList;
650    }
651
652    /**
653     * arguments in rank(value,...) function.
654     * @return a list of {@link TOrderByItem} in function: rank, csum
655     */
656    public TOrderByItemList getOrderByList() {
657
658        return orderByList;
659    }
660
661    private  TOrderBy sortClause;
662
663    public void setSortClause(TOrderBy sortClause) {
664        this.sortClause = sortClause;
665    }
666
667    public TOrderBy getSortClause() {
668
669        return sortClause;
670    }
671
672    /**
673     * Over clause of analytic function
674     * @return over clause
675     */
676    public TWindowDef getWindowDef() {
677        return windowDef;
678    }
679
680    public void setWindowDef(TWindowDef windowDef) {
681
682        this.windowDef = windowDef;
683    }
684
685    public void setFunctionOptionsWithDummy(TDummy dummy){
686        if (dummy == null) return;
687        if (dummy.node2 != null){
688            setWindowDef((TWindowDef)dummy.node2 );
689        }
690        if (dummy.node3 != null){
691            setWithinGroup((TWithinGroup) dummy.node3);
692        }
693    }
694
695     protected TWindowDef windowDef;
696
697//    public void setWindowSpecification(TWindowDef windowSpecification) {
698//        this.windowSpecification = windowSpecification;
699//    }
700
701    /**
702     * @deprecated As of v1.8.6.0, replaced by {@link #windowDef}
703     */
704    private TWindowSpecification windowSpecification;
705
706    private TDatatypeAttribute datatypeAttribute = null;
707
708    public TWindowSpecification getWindowSpecification() {
709        return windowSpecification;
710    }
711
712    /**
713     * Not used.
714     *
715     * @param datatypeAttribute datatype attribute
716     */
717    public void setDatatypeAttribute(TDatatypeAttribute datatypeAttribute) {
718        this.datatypeAttribute = datatypeAttribute;
719    }
720
721    /**
722     * Not used.
723     *
724     * @return datatype attribute
725     */
726    public TDatatypeAttribute getDatatypeAttribute() {
727
728        return datatypeAttribute;
729    }
730
731    /**
732     * one of the YEAR/MONTH/DAY, HOUR/MINUTE/SECOND keywords in extract function
733     *
734     * @return one of the YEAR/MONTH/DAY, HOUR/MINUTE/SECOND keywords in extract function
735     */
736    public TSourceToken getExtract_time_token() {
737        return extract_time_token;
738    }
739
740
741    /**
742     * set one of the YEAR/MONTH/DAY, HOUR/MINUTE/SECOND keyword in extract function
743     *
744     * @param extract_time_token one of the YEAR/MONTH/DAY, HOUR/MINUTE/SECOND token
745     */
746    public void setExtract_time_token(TSourceToken extract_time_token) {
747        this.extract_time_token = extract_time_token;
748    }
749
750
751    private TDummy dummy = null;
752
753    /**
754     * Set value for temporary use only
755     *
756     * @param dummy a temporary value from parse tree
757     */
758    public void setDummy(TDummy dummy) {
759        this.dummy = dummy;
760    }
761
762    /**
763     * Not used
764     *
765     * @return a temporary value
766     */
767    public TDummy getDummy() {
768
769        return dummy;
770    }
771
772    public void setInExpr(TInExpr inExpr) {
773        this.inExpr = inExpr;
774    }
775
776    public TInExpr getInExpr() {
777
778        return inExpr;
779    }
780
781    private TInExpr inExpr = null; //sql server, used in fntContains, fntFreetext
782
783    public void setExtractXMLArg(TExpressionList exprList){
784       if (exprList.size() > 1){
785           this.XMLType_Instance = exprList.getExpression(0);
786           this.XPath_String = exprList.getExpression(1);
787       }
788
789       if (exprList.size() > 2){
790           this.Namespace_String = exprList.getExpression(2);
791       }
792
793       functionType = EFunctionType.extractxml_t;
794
795    }
796    private TExpression XMLType_Instance = null;
797
798    public TExpression getNamespace_String() {
799        return Namespace_String;
800    }
801
802    public TExpression getXPath_String() {
803
804        return XPath_String;
805    }
806
807    public TExpression getXMLType_Instance() {
808
809        return XMLType_Instance;
810    }
811
812    private TExpression XPath_String = null;
813    private TExpression Namespace_String = null;
814
815
816    private TObjectNameList matchColumns = null;
817
818    /**
819     * column list in match function of MySQL
820     * @return
821     */
822    public TObjectNameList getMatchColumns() {
823        return matchColumns;
824    }
825
826    /**
827     * against expr in match function of MySQL
828     * <pre>
829     *     MATCH (col1,col2,...) AGAINST (expr [search_modifier])
830     * </pre>
831     *
832     * @return expression after against keyword
833     */
834    public TExpression getAgainstExpr() {
835
836        return againstExpr;
837    }
838
839    private TExpression againstExpr = null;
840
841    public void setMatchColumns(TObjectNameList matchColumns) {
842        this.matchColumns = matchColumns;
843    }
844
845    /**
846     * against expr in match function of MySQL
847     * <pre>
848     *     MATCH (col1,col2,...) AGAINST (expr [search_modifier])
849     * </pre>
850     * @param againstExpr expression after against keyword
851     */
852    public void setAgainstExpr(TExpression againstExpr) {
853
854        this.againstExpr = againstExpr;
855    }
856
857    private TTypeName typename = null;
858
859    public void setTypename(TTypeName typename) {
860        this.typename = typename;
861    }
862
863    public TTypeName getTypename() {
864
865        return typename;
866    }
867
868    private TExpression parameter;
869
870    public void setParameter(TExpression parameter) {
871        this.parameter = parameter;
872    }
873
874    public void setStyle(TExpression style) {
875        this.style = style;
876    }
877
878    /**
879     * parameter in function:convert(datetype,parameter,style)
880     * @return
881     */
882    public TExpression getParameter() {
883
884        return parameter;
885    }
886
887    /**
888     * style in function:convert(datetype,parameter,style)
889     * @return
890     */
891    public TExpression getStyle() {
892        return style;
893    }
894
895    private TExpression style;
896
897    private TSourceToken extract_time_token = null;
898
899     TExpression expr1 = null; //teradata position function, sql server: convert; oracle convert,translate  , mysql substring
900     TExpression expr2 = null; //teradata: position,substring function,, sql server: convert; oracle convert, mysql substring
901     TExpression expr3 = null; //teradata: substring function, for n, mysql substring
902
903     protected EFunctionType functionType = EFunctionType.udf_t;
904
905    public EFunctionType getFunctionType() {
906        if (functionType != EFunctionType.unknown_t){
907            return functionType;
908        }else if (getFunctionName().toString().toLowerCase().equalsIgnoreCase("contains")){
909            return EFunctionType.contains_t;
910        }else if (isBuiltIn(this.dbvendor)){
911            return  EFunctionType.builtin_t;
912        }else{
913            return functionType;
914        }
915    }
916
917    public boolean hasParenthesis() {
918        // 只有一个token,肯定不包含括号
919        if ((this.getStartToken() != null) && (this.getEndToken() != null) && (this.getStartToken() == this.getEndToken())) return false;
920        if (isOracleBuiltinFunction(this.dbvendor, this.getFunctionName().toString())) {
921            return false;
922        }
923
924        //
925        // 补充其他没有括号的情况
926        //
927
928        return true;
929    }
930
931    private boolean isOracleBuiltinFunction(EDbVendor dbvendor, String functionName) {
932        if (dbvendor != EDbVendor.dbvoracle) return false;
933
934        return functionName.equalsIgnoreCase("sysdate")
935                || functionName.equalsIgnoreCase("user")
936                || functionName.equalsIgnoreCase("SYSTIMESTAMP")
937                || functionName.equalsIgnoreCase("CURRENT_DATE")
938                || functionName.equalsIgnoreCase("CURRENT_TIMESTAMP")
939                ;
940
941    }
942
943    TColumnDefinitionList fieldDefs;
944    TResultColumnList fieldValues;
945
946    public TColumnDefinitionList getFieldDefs() {
947        return fieldDefs;
948    }
949
950    public TResultColumnList getFieldValues() {
951        return fieldValues;
952    }
953
954
955    public TObjectName getFunctionName() {
956        return functionName;
957    }
958
959    protected TObjectName functionName;
960
961    public TExpression Trim_Expr = null;
962    public TExpression Trim_From_Expr = null;
963
964
965    public void setTrimArgument(TTrimArgument trimArgument) {
966        this.trimArgument = trimArgument;
967    }
968
969    public TTrimArgument getTrimArgument() {
970
971        return trimArgument;
972    }
973
974    TTrimArgument trimArgument = null;
975
976
977    public void setExpr1(TExpression expr1) {
978        this.expr1 = expr1;
979    }
980
981    public void setExpr2(TExpression expr2) {
982        this.expr2 = expr2;
983    }
984
985    private TTypeName asDatatype;
986
987    /**
988     *  datatype defined in Oracle function: <code> XMLSERIALIZE(value_expr as datatype)</code>
989     *
990     * @param asDatatype datatype defined in Oracle function: <code> XMLSERIALIZE(value_expr as datatype)</code>
991     */
992    public void setAsDatatype(TTypeName asDatatype) {
993        this.asDatatype = asDatatype;
994    }
995
996    private TResultColumnList XMLForestValueList;
997
998    public void setXMLForestValueList(TResultColumnList XMLForestValueList) {
999        this.XMLForestValueList = XMLForestValueList;
1000    }
1001
1002    private TExpression XMLElementNameExpr;
1003
1004    public void setXMLElementNameExpr(TExpression XMLElementNameExpr) {
1005        this.XMLElementNameExpr = XMLElementNameExpr;
1006    }
1007
1008    /**
1009     * XMLElement name/evalname expr
1010     * @return XMLElement name/evalname expr
1011     */
1012    public TExpression getXMLElementNameExpr() {
1013        return XMLElementNameExpr;
1014
1015    }
1016
1017    private TXMLAttributesClause XMLAttributesClause;
1018
1019    public void setXMLAttributesClause(TXMLAttributesClause XMLAttributesClause) {
1020        this.XMLAttributesClause = XMLAttributesClause;
1021    }
1022
1023    public void setXmlPassingClause(TXMLPassingClause xmlPassingClause) {
1024        this.xmlPassingClause = xmlPassingClause;
1025    }
1026
1027    public TXMLPassingClause getXmlPassingClause() {
1028        return xmlPassingClause;
1029    }
1030
1031    TXMLPassingClause xmlPassingClause;
1032
1033
1034    private TResultColumnList XMLElementValueExprList;
1035
1036    public void setXMLElementValueExprList(TResultColumnList XMLElementValueExprList) {
1037        this.XMLElementValueExprList = XMLElementValueExprList;
1038    }
1039
1040    /**
1041     * XMLElement ( value_expr [,XML_attribute_clause] [,value expr list] )
1042     * @return XMLElement value expr list
1043     */
1044    public TResultColumnList getXMLElementValueExprList() {
1045
1046        return XMLElementValueExprList;
1047    }
1048
1049    /**
1050     * XMLAttribute clause in xmlelement function
1051     * @return XMLAttribute clause in xmlelement function
1052     */
1053    public TXMLAttributesClause getXMLAttributesClause() {
1054
1055        return XMLAttributesClause;
1056    }
1057
1058    /**
1059     * XMLFOREST (value_expr [as aliasName], ... )
1060     * @return XMLFOREST value list
1061     */
1062    public TResultColumnList getXMLForestValueList() {
1063
1064        return XMLForestValueList;
1065    }
1066
1067    /**
1068     * get datatype defined in Oracle XMLSERIALIZE(value_expr as datatype)
1069     *
1070     * @return datatype defined in oracle XMLSERIALIZE function
1071     */
1072    public TTypeName getAsDatatype() {
1073
1074        return asDatatype;
1075    }
1076
1077    /**
1078     * paramter of following functions
1079     * <br>teradata: position function,
1080     * <br>sql server: convert;
1081     * <br>oracle: convert,translate,cast,oracle XMLSERIALIZE(value_expr), oracle XMLROOT (value_expr)
1082     * <br>mysql: substring
1083     * @return
1084     */
1085    public TExpression getExpr1() {
1086
1087        return expr1;
1088    }
1089
1090    public TExpression getExpr2() {
1091        return expr2;
1092    }
1093
1094    public void setExpr3(TExpression expr3) {
1095        this.expr3 = expr3;
1096    }
1097
1098    public TExpression getExpr3() {
1099
1100        return expr3;
1101    }
1102
1103
1104    public void setExprList(TExpressionList exprList) {
1105        this.exprList = exprList;
1106    }
1107
1108    /**
1109     * return TExpressionList instead of TGroupingExpressionItemList after v1.4.3.3
1110     * @return    expr list
1111     */
1112    public TExpressionList getExprList() {
1113
1114        return exprList;
1115    }
1116
1117    private TExpressionList exprList = null;//teradata case_n, range_n
1118
1119
1120    protected TExpressionList Args = null;
1121
1122    public void setArgs(TExpressionList args) {
1123        Args = args;
1124    }
1125
1126
1127    public void init(Object arg1){
1128        functionName = (TObjectName)arg1;
1129        if (functionName.getDbObjectType() == EDbObjectType.unknown){
1130            functionName.setObjectType(TObjectName.ttobjFunctionName);
1131        }
1132    }
1133
1134    public void init(Object arg1,Object arg2){
1135        if (arg1 instanceof EFunctionType){
1136            functionType  = (EFunctionType)arg1;
1137            init(arg2);
1138        }
1139        else if (arg1 instanceof TObjectName){
1140            functionType  = (EFunctionType)arg2;
1141            init(arg1);
1142        }
1143        switch (functionType){
1144            case xmlmethod_t:
1145                if (functionName.getMethodToken().tokencode == TBaseType.rrw_xml_nodes){
1146                    functionType = EFunctionType.xmlnodes_t;
1147                }else if (functionName.getMethodToken().tokencode == TBaseType.rrw_xml_query){
1148                    functionType = EFunctionType.xml_sqlserver_query_t;
1149                }else if (functionName.getMethodToken().tokencode == TBaseType.rrw_xml_value){
1150                    functionType = EFunctionType.xmlvalue_t;
1151                }else if (functionName.getMethodToken().tokencode == TBaseType.rrw_xml_exist){
1152                    functionType = EFunctionType.xmlexists_t;
1153                }else if (functionName.getMethodToken().tokencode == TBaseType.rrw_xml_modify){
1154                    functionType = EFunctionType.xmlmodify_t;
1155                }
1156                break;
1157            case oracle_dbms_package_t:
1158                this.isBuiltIn = true;
1159                break;
1160            default:
1161                break;
1162        }
1163    }
1164
1165    public void init(Object arg1,Object arg2,Object arg3){
1166        init(arg1,arg2);
1167        // For struct_t functions, store the field values (TResultColumnList)
1168        if (arg3 instanceof TResultColumnList) {
1169            if (this.functionType == EFunctionType.struct_t) {
1170                this.fieldValues = (TResultColumnList) arg3;
1171            }
1172        }
1173    }
1174
1175    public void init(Object arg1,Object arg2,Object arg3,Object arg4){
1176        init(arg1,arg2,arg3);
1177        // For struct_t functions, store the field values (TResultColumnList)
1178        if (arg4 instanceof TResultColumnList) {
1179            if (this.functionType == EFunctionType.struct_t) {
1180                this.fieldValues = (TResultColumnList) arg4;
1181            }
1182        }
1183    }
1184
1185
1186    public void setAnalyticFunction(TAnalyticFunction analyticFunction) {
1187        this.analyticFunction = analyticFunction;
1188    }
1189
1190    /**
1191     * get the list of parameters defined in this function
1192     *
1193     * @return the list of parameter
1194     */
1195    public TExpressionList getArgs() {
1196        return Args;
1197    }
1198
1199     protected TAnalyticFunction analyticFunction;
1200
1201
1202    public void doParse(TCustomSqlStatement psql, ESqlClause plocation){
1203        this.dbvendor = psql.dbvendor;
1204        switch(functionType){
1205            case unknown_t:
1206            case chr_t:
1207            case udf_t:
1208            case builtin_t:
1209            case listagg_t:
1210            case year_t:
1211            case generate_date_array_t:
1212                if (callTarget != null){
1213                    callTarget.doParse(psql,plocation);
1214                }
1215                if (Args != null){
1216                    boolean check_first_arg = true;
1217                    if ((psql.dbvendor == EDbVendor.dbvsybase)||(psql.dbvendor == EDbVendor.dbvmssql)||(psql.dbvendor == EDbVendor.dbvredshift)
1218                        ){
1219                        check_first_arg = !((functionName.toString().equalsIgnoreCase("dateadd"))
1220                                ||(functionName.toString().equalsIgnoreCase("datediff"))
1221                                ||(functionName.toString().equalsIgnoreCase("datename"))
1222                                ||(functionName.toString().equalsIgnoreCase("datepart"))
1223                        );
1224                    }
1225                    for(int i=0;i<Args.size();i++){
1226                        if ((!check_first_arg)&&(i==0)) {
1227                            // mark the first argument in datediff to
1228                            setFirstArgAsDateTimePart(i);
1229                            continue;
1230                        }
1231                        Args.getExpression(i).doParse(psql,plocation);
1232                    }
1233                }
1234
1235                if (psql.dbvendor == EDbVendor.dbvmssql){
1236                    // check OGC function of sql server
1237//                    System.out.println("func:"+functionName.toString());
1238                    if (isSQLServerOGCMethod(functionName.getObjectToken())){
1239                        if (functionName.getSchemaToken() != null){
1240                            functionName.getSchemaToken().setDbObjType(TObjectName.ttobjColumn);
1241                            if (functionName.getDatabaseToken() != null){
1242                                functionName.getDatabaseToken().setDbObjType(TObjectName.ttobjTable);
1243                            }
1244
1245                            TObjectName objectName = new TObjectName();
1246                            objectName.init(functionName.getDatabaseToken(),functionName.getSchemaToken());
1247                            objectName.setGsqlparser(psql.getGsqlparser()); // this will make toString work correctly
1248                            psql.linkColumnReferenceToTable(objectName,plocation);
1249                            psql.linkColumnToTable(objectName,plocation);
1250                        }
1251                    }else if (isSQLServerFunctionsONXMLColumn()) {
1252
1253
1254//                        if (functionName.getSchemaToken() != null) {
1255//                            functionName.getSchemaToken().setDbObjType(TObjectName.ttobjColumn);
1256//                            functionName.setPartToken(functionName.getSchemaToken());
1257//                            functionName.setSchemaToken(null);
1258//                            if (functionName.getDatabaseToken() != null) {
1259//                                functionName.getDatabaseToken().setDbObjType(TObjectName.ttobjTable);
1260//                                functionName.setObjectToken(functionName.getDatabaseToken());
1261//                            }
1262//
1263//                            TObjectName objectName = new TObjectName();
1264//                            objectName.init(functionName.getObjectToken(), functionName.getPartToken());
1265//                            objectName.setGsqlparser(psql.getGsqlparser()); // this will make toString work correctly
1266//                            psql.linkColumnReferenceToTable(objectName, plocation);
1267//                            psql.linkColumnToTable(objectName, plocation);
1268//                        }
1269
1270                    }
1271                } else if (psql.dbvendor == EDbVendor.dbvoracle){
1272                    if (plocation == ESqlClause.spAssignValue){
1273                        if (functionName.getNumberOfPart() == 3){
1274                            // schema1.pkg1.GETCUSTOMERNAME(2)
1275                            functionName.setPackageToken(functionName.getSchemaToken());
1276                            functionName.setSchemaToken(functionName.getDatabaseToken());
1277                            functionName.setServerToken(null);
1278                        }
1279                    }
1280                }
1281                break;
1282            case trim_t:
1283                if (this.trimArgument != null){
1284                this.trimArgument.doParse(psql,plocation);
1285                }
1286
1287                break;
1288            case cast_t:
1289                if (this.expr1 != null){
1290                    this.expr1.doParse(psql,plocation);
1291                }else{
1292                    this.getArgs().getExpression(0).doParse(psql,plocation);
1293                }
1294
1295                break;
1296            case convert_t:
1297                if (this.typename != null) this.typename.doParse(psql,plocation);
1298                this.parameter.doParse(psql,plocation);
1299                if (this.style != null)
1300                { //sql server
1301                    this.style.doParse(psql,plocation);
1302                }
1303                break;
1304            case extract_t:
1305                if (this.expr1 != null){
1306                    this.expr1.doParse(psql,plocation);
1307                }
1308                break;
1309            case treat_t:
1310                this.expr1.doParse(psql,plocation);
1311                break;
1312            case contains_t:
1313                //this.inExpr.doParse(psql,plocation);
1314
1315                this.expr1.doParse(psql,plocation);
1316                this.expr2.doParse(psql,plocation);
1317                break;
1318            case freetext_t:
1319                //inExpr.doParse(psql,plocation);
1320                this.expr1.doParse(psql,plocation);
1321                this.expr2.doParse(psql,plocation);
1322                break;
1323            case case_n_t:
1324                this.getArgs().doParse(psql, plocation);
1325                break;
1326//            case range_n_t:
1327//                this.expr1.doParse(psql,plocation);
1328//                for(TRangeNFunctionItem rangeItem : rangeNFunctionItems){
1329//                    rangeItem.doParse(psql,plocation);
1330//                }
1331//                break;
1332            case position_t:
1333                expr1.doParse(psql,plocation);
1334                expr2.doParse(psql,plocation);
1335                break;
1336            case substring_t:
1337                if (Args != null)
1338                    for(int i=0;i<Args.size();i++){
1339                        Args.getExpression(i).doParse(psql,plocation);
1340                    }
1341                if (expr1 != null) expr1.doParse(psql,plocation);
1342                if (expr2 != null) expr2.doParse(psql,plocation);
1343                if (expr3 != null){
1344                    expr3.doParse(psql,plocation);
1345                }
1346                break;
1347            case xmlquery_t:
1348                if (xmlPassingClause != null){
1349                    xmlPassingClause.doParse(psql,plocation);
1350                }
1351                break;
1352            case xmlcast_t:
1353                if (typeExpression != null){
1354                    typeExpression.doParse(psql,plocation);
1355                }
1356                break;
1357            case match_against_t:
1358                for(int i=0;i<this.getMatchColumns().size();i++){
1359                    psql.linkColumnReferenceToTable(this.getMatchColumns().getObjectName(i),plocation);
1360                    psql.linkColumnToTable(this.getMatchColumns().getObjectName(i),plocation);
1361                }
1362                this.getAgainstExpr().doParse(psql,plocation);
1363                break;
1364            case adddate_t:
1365            case date_add_t:
1366            case subdate_t:
1367            case date_sub_t:
1368            case timestampadd_t:
1369            case timestampdiff_t:
1370                expr1.doParse(psql,plocation);
1371                expr2.doParse(psql,plocation);
1372                break;
1373            case xmlserialize_t:
1374                if (expr1 != null){
1375                    expr1.doParse(psql,plocation);
1376                }else if (typeExpression != null){
1377                    typeExpression.doParse(psql,plocation);
1378                }
1379                break;
1380            case xmlroot_t:
1381                expr1.doParse(psql,plocation);
1382                break;
1383            case xmlforest_t:
1384                XMLForestValueList.doParse(psql, plocation);
1385                break;
1386            case xmlelement_t:
1387                if (XMLElementNameExpr.getExpressionType() == EExpressionType.simple_object_name_t){
1388                    XMLElementNameExpr.getObjectOperand().setDbObjectType(EDbObjectType.xmlElement);
1389                }
1390                XMLElementNameExpr.doParse(psql,ESqlClause.xmlElementName);
1391                if (XMLAttributesClause != null)
1392                  XMLAttributesClause.doParse(psql,plocation);
1393                if (XMLElementValueExprList != null)
1394                    XMLElementValueExprList.doParse(psql,plocation);
1395                break;
1396            case translate_t:
1397                expr1.doParse(psql,plocation);
1398                if (expr2 != null)  expr2.doParse(psql,plocation);
1399                if (expr3 != null)  expr3.doParse(psql,plocation);
1400                break;
1401            case group_concat_t:
1402                groupConcatParam.doParse(psql,plocation);
1403                break;
1404            case quantile_t:
1405                this.orderByList.doParse(psql,plocation);
1406                break;
1407            case csum_t:
1408                this.getOrderByList().doParse(psql,plocation);
1409                break;
1410            case rank_t:
1411                if (this.getOrderByList() != null){
1412                    this.getOrderByList().doParse(psql,plocation);
1413                }
1414
1415                break;
1416            case xmlexists_t:
1417            case xmlmodify_t:
1418            case xmlnodes_t:
1419            case xmlvalue_t:
1420            case xml_sqlserver_query_t:
1421                if (callTarget != null){
1422                    callTarget.doParse(psql,plocation);
1423                }
1424                if ((functionName.getObjectToken() != null)&&(functionName.getPartToken() != null)){
1425                    TObjectName objectName = new TObjectName();
1426                    objectName.init(functionName.getObjectToken(), functionName.getPartToken());
1427                    objectName.setGsqlparser(psql.getGsqlparser()); // this will make toString work correctly
1428                    psql.linkColumnReferenceToTable(objectName, plocation);
1429                    psql.linkColumnToTable(objectName, plocation);
1430                }
1431                break;
1432            case xmlagg_t:
1433                for(int i=0;i<Args.size();i++){
1434                    Args.getExpression(i).doParse(psql,plocation);
1435                }
1436                if (getSortClause() != null){
1437                    getSortClause().doParse(psql,plocation);
1438                }
1439                break;
1440            case if_t:
1441                expr1.doParse(psql,plocation);
1442                expr2.doParse(psql,plocation);
1443                expr3.doParse(psql,plocation);
1444                break;
1445            case array_t: // bigquery array (subquery)
1446                this.getArgs().getExpression(0).doParse(psql,plocation);
1447                break;
1448            case array_agg_t:
1449                this.getArgs().getExpression(0).doParse(psql,plocation);
1450                break;
1451            case string_agg_t:
1452                this.getArgs().getExpression(0).doParse(psql,plocation);
1453                if (getOrderByList() != null){
1454                    getOrderByList().doParse(psql,plocation);
1455                }
1456                break;
1457            default:
1458                if (getArgs() != null){
1459                    for(int i=0;i<getArgs().size();i++){
1460                        Args.getExpression(i).doParse(psql,plocation);
1461                    }
1462                }
1463                break;
1464        }
1465
1466        if (withinGroup != null){
1467            withinGroup.doParse(psql,plocation);
1468        }
1469        if (analyticFunction != null){
1470            analyticFunction.doParse(psql,plocation);
1471        }
1472
1473        if (filterClause != null){
1474            filterClause.doParse(psql,plocation);
1475        }
1476
1477        if (windowDef != null){
1478            windowDef.doParse(psql,plocation);
1479        }
1480    }
1481
1482
1483    /**
1484     * @deprecated As of v1.8.6.3, use {@link #getWindowDef()} instead
1485     * window clause in window function.
1486     * @return a value of {@link TAnalyticFunction}
1487     * @see TAnalyticFunction
1488     */
1489    public TAnalyticFunction getAnalyticFunction() {
1490        return analyticFunction;
1491    }
1492
1493    public void accept(TParseTreeVisitor v){
1494        v.preVisit(this);
1495        v.postVisit(this);
1496    }
1497
1498    public void acceptChildren(TParseTreeVisitor v){
1499        v.preVisit(this);
1500        functionName.acceptChildren(v);
1501        switch(functionType){
1502            case unknown_t:
1503                if (Args != null){
1504                    Args.acceptChildren(v);
1505                }
1506                break;
1507            case udf_t:
1508                if (Args != null){
1509                    Args.acceptChildren(v);
1510                }
1511                if (analyticFunction != null){
1512                    analyticFunction.acceptChildren(v);
1513                }
1514                break;
1515            case trim_t:
1516                if (this.trimArgument != null){
1517                    this.trimArgument.acceptChildren(v);
1518                }
1519
1520                break;
1521            case cast_t:
1522                if (this.expr1 != null) {
1523                    this.expr1.acceptChildren(v);
1524                }else{
1525                    this.getArgs().getExpression(0).acceptChildren(v);
1526                }
1527
1528                break;
1529            case convert_t:
1530                if (this.typename != null) this.typename.acceptChildren(v);
1531                if (this.parameter != null) this.parameter.acceptChildren(v);
1532                if (this.style != null) this.style.acceptChildren(v);
1533//                this.expr1.acceptChildren(v);
1534//                if (this.expr2 != null)
1535//                { //sql server
1536//                    this.expr2.acceptChildren(v);
1537//                }
1538                break;
1539            case extract_t:
1540                if (this.expr1 != null){
1541                    this.expr1.acceptChildren(v);
1542                }
1543                break;
1544            case treat_t:
1545                this.expr1.acceptChildren(v);
1546                break;
1547            case contains_t:
1548                //this.inExpr.acceptChildren(v);
1549
1550                this.expr1.acceptChildren(v);
1551                this.expr2.acceptChildren(v);
1552                break;
1553            case freetext_t:
1554                //inExpr.acceptChildren(v);
1555                this.expr1.acceptChildren(v);
1556                this.expr2.acceptChildren(v);
1557                break;
1558            case case_n_t:
1559                this.getArgs().acceptChildren(v);
1560                break;
1561//            case range_n_t:
1562//                this.expr1.acceptChildren(v);
1563//                for(TRangeNFunctionItem item:rangeNFunctionItems){
1564//                    item.acceptChildren(v);
1565//                }
1566//
1567//                break;
1568            case position_t:
1569                expr1.acceptChildren(v);
1570                expr2.acceptChildren(v);
1571                break;
1572            case substring_t:
1573                if (Args != null){
1574                    Args.acceptChildren(v);
1575                }
1576                if (expr1 != null) expr1.acceptChildren(v);
1577                if (expr2 != null) expr2.acceptChildren(v);
1578                if (expr3 != null){
1579                    expr3.acceptChildren(v);
1580                }
1581                break;
1582            case xmlquery_t:
1583                break;
1584            case xmlcast_t:
1585                break;
1586            case match_against_t:
1587                //for(int i=0;i<this.getMatchColumns().size();i++){
1588                //    psql.linkColumnReferenceToTable(this.getMatchColumns().getObjectName(i),plocation);
1589                //}
1590                this.getAgainstExpr().acceptChildren(v);
1591                break;
1592            case adddate_t:
1593            case date_add_t:
1594            case subdate_t:
1595            case date_sub_t:
1596            case timestampadd_t:
1597            case timestampdiff_t:
1598                expr1.acceptChildren(v);
1599                expr2.acceptChildren(v);
1600                break;
1601            default:
1602                if (Args != null){
1603                    Args.acceptChildren(v);
1604                }
1605                break;
1606        }
1607
1608        if (analyticFunction != null){
1609            analyticFunction.acceptChildren(v);
1610        }
1611
1612        if (filterClause != null){
1613            filterClause.acceptChildren(v);
1614        }
1615
1616        if (windowDef != null){
1617            windowDef.acceptChildren(v);
1618        }
1619
1620        v.postVisit(this);
1621    }
1622
1623     boolean isSQLServerFunctionsONXMLColumn(){
1624//        return ((st.tokencode == TBaseType.rrw_xml_exist)
1625//                ||(st.tokencode == TBaseType.rrw_xml_query)
1626//                ||(st.tokencode == TBaseType.rrw_xml_modify)
1627//                ||(st.tokencode == TBaseType.rrw_xml_nodes)
1628//                ||(st.tokencode == TBaseType.rrw_xml_value)
1629//                );
1630        return ((this.functionType == EFunctionType.xmlmodify_t)
1631                ||(this.functionType == EFunctionType.xmlvalue_t)
1632                ||(this.functionType == EFunctionType.xmlnodes_t)
1633                ||(this.functionType == EFunctionType.xmlexists_t)
1634                ||(this.functionType == EFunctionType.xmlquery_t)
1635        );
1636    }
1637
1638     boolean isSQLServerOGCMethod(TSourceToken st){
1639        return ((st.tokencode == TBaseType.rrw_starea)
1640                ||(st.tokencode == TBaseType.rrw_stasbinary)
1641                ||(st.tokencode == TBaseType.rrw_stastext)
1642                ||(st.tokencode == TBaseType.rrw_stbuffer)
1643                ||(st.tokencode == TBaseType.rrw_stdimension)
1644                ||(st.tokencode == TBaseType.rrw_stdisjoint)
1645                ||(st.tokencode == TBaseType.rrw_stdistance)
1646                ||(st.tokencode == TBaseType.rrw_stendpoint)
1647                ||(st.tokencode == TBaseType.rrw_stgeometryn)
1648                ||(st.tokencode == TBaseType.rrw_stgeometrytype)
1649                ||(st.tokencode == TBaseType.rrw_stintersection)
1650                ||(st.tokencode == TBaseType.rrw_stintersects)
1651                ||(st.tokencode == TBaseType.rrw_stisclosed)
1652                ||(st.tokencode == TBaseType.rrw_stisempty)
1653                ||(st.tokencode == TBaseType.rrw_stlength)
1654                ||(st.tokencode == TBaseType.rrw_stnumgeometries)
1655                ||(st.tokencode == TBaseType.rrw_stnumpoints)
1656                ||(st.tokencode == TBaseType.rrw_stpointn)
1657                ||(st.tokencode == TBaseType.rrw_stsrid)
1658                ||(st.tokencode == TBaseType.rrw_ststartpoint)
1659                ||(st.tokencode == TBaseType.rrw_stunion)
1660                );
1661    }
1662
1663    /**
1664     * @deprecated As of v1.4.3.0, replaced by {@link #functionType}
1665     */
1666    private int funcType = fntUdf;
1667
1668    /**
1669     * @deprecated As of v1.4.3.0
1670     */
1671    public void setFuncType(int funcType) {
1672        this.funcType = funcType;
1673
1674    }
1675
1676    /**
1677     * @deprecated As of v1.4.3.0, replaced by {@link #getFunctionType()}.
1678     */
1679    public int getFuncType() {
1680
1681        return funcType;
1682    }
1683
1684    /**
1685     * @deprecated As of v1.4.3.0, replaced by {@link EFunctionType#udf_t}
1686     */
1687    public final static int fntUdf = 0;
1688
1689    /**
1690     * @deprecated As of v1.4.3.0, replaced by {@link EFunctionType#trim_t}
1691     */
1692    public final static int fntTrim = 1;
1693
1694    /**
1695     * @deprecated As of v1.4.3.0, replaced by {@link EFunctionType#cast_t}
1696     */
1697    public final static int fntCast = 2;
1698
1699    /**
1700     * @deprecated As of v1.4.3.0, replaced by {@link EFunctionType#convert_t}
1701     */
1702    public final static int fntConvert = 3;
1703
1704    /**
1705     * @deprecated As of v1.4.3.0, replaced by {@link EFunctionType#extract_t}
1706     */
1707    public final static int fntExtract = 4;
1708
1709    /**
1710     * @deprecated As of v1.4.3.0, replaced by {@link EFunctionType#treat_t}
1711     */
1712    public final static int fntTreat = 5;
1713
1714    /**
1715     * @deprecated As of v1.4.3.0, replaced by {@link EFunctionType#contains_t}
1716     */
1717    public final static int fntContains = 6;
1718
1719    /**
1720     * @deprecated As of v1.4.3.0, replaced by {@link EFunctionType#freetext_t}
1721     */
1722    public final static int fntFreetext = 7; //
1723
1724    /**
1725     * @deprecated As of v1.4.3.0, replaced by {@link EFunctionType#case_n_t}
1726     */
1727    public final static int fntCaseN = 10; //teradata
1728
1729    /**
1730     * @deprecated As of v1.4.3.0, replaced by {@link EFunctionType#range_n_t}
1731     */
1732    public final static int fntRangeN = 11; //teradata
1733
1734    /**
1735     * @deprecated As of v1.4.3.0, replaced by {@link EFunctionType#position_t}
1736     */
1737    public final static int fntPosition = 12; //teradata
1738    /**
1739     * @deprecated As of v1.4.3.0, replaced by {@link EFunctionType#substring_t}
1740     */
1741    public final static int fntSubstring = 13; //teradata
1742    /**
1743     * @deprecated As of v1.4.3.0, replaced by {@link EFunctionType#translate_t}
1744     */
1745    public final static int fntTranslate = 14; //teradata ,oracle
1746    /**
1747     * @deprecated As of v1.4.3.0, replaced by {@link EFunctionType#translate_chk_t}
1748     */
1749    public final static int fntTranslateCHK = 15; //teradata
1750    /**
1751     * @deprecated As of v1.4.3.0, replaced by {@link EFunctionType#csum_t}
1752     */
1753    public final static int fntCSUM = 16; //teradata
1754    /**
1755     * @deprecated As of v1.4.3.0, replaced by {@link EFunctionType#rank_t}
1756     */
1757    public final static int fntRank = 17; //teradata
1758    /**
1759     * @deprecated As of v1.4.3.0, replaced by {@link EFunctionType#xmlquery_t}
1760     */
1761    public final static int fntXmlQuery= 18; //oracle
1762
1763    /**
1764     * @deprecated As of v1.4.3.0, replaced by {@link EFunctionType#substring_t}
1765     */
1766    public final static int fntSubString  = 31;//mysql
1767    /**
1768     * @deprecated As of v1.4.3.0, replaced by {@link EFunctionType#adddate_t}
1769     */
1770    public final static int fntAddDate  = 32;//mysql
1771    /**
1772     * @deprecated As of v1.4.3.0, replaced by {@link EFunctionType#date_add_t}
1773     */
1774    public final static int fntDateAdd  = 33;//mysql
1775    /**
1776     * @deprecated As of v1.4.3.0, replaced by {@link EFunctionType#subdate_t}
1777     */
1778    public final static int fntSubDate  = 34;//mysql
1779    /**
1780     * @deprecated As of v1.4.3.0, replaced by {@link EFunctionType#date_sub_t}
1781     */
1782    public final static int fntDateSub  = 35;//mysql
1783    /**
1784     * @deprecated As of v1.4.3.0, replaced by {@link EFunctionType#timestampadd_t}
1785     */
1786    public final static int fntTimestampAdd  = 36;//mysql
1787    /**
1788     * @deprecated As of v1.4.3.0, replaced by {@link EFunctionType#timestampdiff_t}
1789     */
1790    public final static int fntTimestampDiff  = 37;//mysql
1791    /**
1792     * @deprecated As of v1.4.3.0, replaced by {@link EFunctionType#group_concat_t}
1793     */
1794    public final static int fntGroupConcat  = 38;//mysql
1795    /**
1796     * @deprecated As of v1.4.3.0, replaced by {@link EFunctionType#match_against_t}
1797     */
1798    public final static int fntMatchAgainst  = 39;//mysql
1799
1800    /**
1801     * @deprecated As of v1.4.3.0, replaced by {@link EFunctionType#extract_t}
1802     */
1803    public final static int fntExtractXML  = 50;//oracle
1804
1805
1806    /**
1807     * @deprecated As of v1.4.3.0, replaced by {@link EFunctionType#ogc_t}
1808     */
1809    public final static int fntOGC  = 60;
1810
1811    public void setCheckedBuiltIn(boolean isCheckedBuiltIn) {
1812        this.isCheckedBuiltIn = isCheckedBuiltIn;
1813    }
1814
1815    public void setBuiltIn(boolean isBuiltIn) {
1816        this.isBuiltIn = isBuiltIn;
1817    }
1818
1819    public void setXMLType_Instance(TExpression XMLType_Instance) {
1820        this.XMLType_Instance = XMLType_Instance;
1821    }
1822
1823    public void setXPath_String(TExpression XPath_String) {
1824        this.XPath_String = XPath_String;
1825    }
1826
1827    public void setNamespace_String(TExpression namespace_String) {
1828        Namespace_String = namespace_String;
1829    }
1830
1831    public void setFunctionType(EFunctionType functionType) {
1832        this.functionType = functionType;
1833    }
1834
1835    public void setFunctionName(TObjectName functionName) {
1836        this.functionName = functionName;
1837    }
1838
1839    public void setTrim_Expr(TExpression trim_Expr) {
1840        Trim_Expr = trim_Expr;
1841    }
1842
1843    public void setTrim_From_Expr(TExpression trim_From_Expr) {
1844        Trim_From_Expr = trim_From_Expr;
1845    }
1846
1847}