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