001package gudusoft.gsqlparser.nodes;
002
003import gudusoft.gsqlparser.*;
004
005import java.util.ArrayList;
006
007public class TTableFunction extends TFunctionCall implements IRelation {
008    ArrayList<TAttributeNode> relationAttributes = new ArrayList<>();
009
010    @Override
011    public int size(){
012        return relationAttributes.size();
013    }
014
015    @Override
016    public ArrayList<TAttributeNode> getAttributes(){
017        return relationAttributes;
018    };
019
020    @Override
021    public String getRelationName(){
022        return this.getFunctionName().toString();
023    };
024
025   public void initAttributes(){
026        if (fieldDefs == null) return;
027        int c = 0;
028        TResultColumn rc = null;
029        for(TColumnDefinition cd:fieldDefs){
030            if (fieldValues != null){
031                rc = fieldValues.getResultColumn(c);
032                c++;
033            }
034            TAttributeNode node = new TAttributeNode(cd.getColumnName().toString(),null,cd,rc);
035            //relationAttributes.add(node);
036            TAttributeNode.addNodeToList(node,relationAttributes);
037        }
038    }
039
040
041
042
043    public void init(Object arg1,Object arg2,Object arg3){
044        init(arg1,arg2);
045        switch (functionType){
046            case struct_t:
047                this.fieldValues = (TResultColumnList)arg3;
048                break;
049        }
050    }
051
052    public void init(Object arg1,Object arg2,Object arg3,Object arg4){
053        init(arg1,arg2,arg3);
054        switch (functionType){
055            case struct_t:
056                this.fieldDefs = (TColumnDefinitionList) arg4;
057                break;
058        }
059    }
060
061    public void doParse(TCustomSqlStatement psql, ESqlClause plocation){
062        this.dbvendor = psql.dbvendor;
063        switch(this.getFunctionType()){
064            case unknown_t:
065            case chr_t:
066            case udf_t:
067            case builtin_t:
068            case listagg_t:
069            case year_t:
070                if (Args != null){
071                    boolean check_first_arg = true;
072                    if ((psql.dbvendor == EDbVendor.dbvsybase)||(psql.dbvendor == EDbVendor.dbvmssql)){
073                        check_first_arg = !((functionName.toString().equalsIgnoreCase("dateadd"))
074                                ||(functionName.toString().equalsIgnoreCase("datediff"))
075                                ||(functionName.toString().equalsIgnoreCase("datename"))
076                                ||(functionName.toString().equalsIgnoreCase("datepart"))
077                        );
078                    }
079                    for(int i=0;i<Args.size();i++){
080                        if ((!check_first_arg)&&(i==0)) {
081                            // mark the first argument in datediff to
082                            setFirstArgAsDateTimePart(i);
083                            continue;
084                        }
085                        Args.getExpression(i).doParse(psql,plocation);
086                    }
087                }
088
089                if (psql.dbvendor == EDbVendor.dbvmssql){
090                    // check OGC function of sql server
091//                    System.out.println("func:"+functionName.toString());
092                    if (isSQLServerOGCMethod(functionName.getObjectToken())){
093                        if (functionName.getSchemaToken() != null){
094                            functionName.getSchemaToken().setDbObjType(TObjectName.ttobjColumn);
095                            if (functionName.getDatabaseToken() != null){
096                                functionName.getDatabaseToken().setDbObjType(TObjectName.ttobjTable);
097                            }
098
099                            TObjectName objectName = new TObjectName();
100                            objectName.init(functionName.getDatabaseToken(),functionName.getSchemaToken());
101                            objectName.setGsqlparser(psql.getGsqlparser()); // this will make toString work correctly
102                            psql.linkColumnReferenceToTable(objectName,plocation);
103                            psql.linkColumnToTable(objectName,plocation);
104                        }
105                    }else if (isSQLServerFunctionsONXMLColumn()) {
106
107
108
109                    }
110                } else if (psql.dbvendor == EDbVendor.dbvoracle){
111                    if (plocation == ESqlClause.spAssignValue){
112                        if (functionName.getNumberOfPart() == 3){
113                            // schema1.pkg1.GETCUSTOMERNAME(2)
114                            functionName.setPackageToken(functionName.getSchemaToken());
115                            functionName.setSchemaToken(functionName.getDatabaseToken());
116                            functionName.setServerToken(null);
117                        }
118                    }
119                }
120                break;
121
122            case xmlquery_t:
123                if (xmlPassingClause != null){
124                    xmlPassingClause.doParse(psql,plocation);
125                }
126                break;
127
128            case struct_t:
129                if (fieldValues != null){
130                    fieldValues.doParse(psql,plocation);
131                }
132                if (fieldDefs != null){
133                    fieldDefs.doParse(psql,plocation);
134                }
135                break;
136            case if_t:
137                expr1.doParse(psql,plocation);
138                expr2.doParse(psql,plocation);
139                expr3.doParse(psql,plocation);
140                break;
141            case array_t: // bigquery array (subquery)
142                this.getArgs().getExpression(0).doParse(psql,plocation);
143                break;
144            case array_agg_t:
145                this.getArgs().getExpression(0).doParse(psql,plocation);
146                break;
147            default:;
148        }
149
150        if (withinGroup != null){
151            withinGroup.doParse(psql,plocation);
152        }
153        if (analyticFunction != null){
154            analyticFunction.doParse(psql,plocation);
155        }
156
157        if (filterClause != null){
158            filterClause.doParse(psql,plocation);
159        }
160
161        if (windowDef != null){
162            windowDef.doParse(psql,plocation);
163        }
164    }
165
166    public void accept(TParseTreeVisitor v){
167        v.preVisit(this);
168        v.postVisit(this);
169    }
170
171    public void acceptChildren(TParseTreeVisitor v){
172        v.preVisit(this);
173        this.getFunctionName().acceptChildren(v);
174        switch(this.getFunctionType()){
175            case unknown_t:
176                if (this.getArgs() != null){
177                    this.getArgs().acceptChildren(v);
178                }
179                break;
180            case udf_t:
181                if (this.getArgs() != null){
182                    this.getArgs().acceptChildren(v);
183                }
184                break;
185            case case_n_t:
186                this.getArgs().acceptChildren(v);
187                break;
188
189            case xmlquery_t:
190                break;
191            case xmlcast_t:
192                break;
193            case match_against_t:
194                //for(int i=0;i<this.getMatchColumns().size();i++){
195                //    psql.linkColumnReferenceToTable(this.getMatchColumns().getObjectName(i),plocation);
196                //}
197                this.getAgainstExpr().acceptChildren(v);
198                break;
199            case struct_t:
200                if (fieldValues != null){
201                    fieldValues.acceptChildren(v);
202                }
203                if (fieldDefs != null){
204                    fieldDefs.acceptChildren(v);
205                }
206                break;
207
208            default:
209                if (this.getArgs() != null){
210                    this.getArgs().acceptChildren(v);
211                }
212                break;
213        }
214
215        if (this.getAnalyticFunction() != null){
216            this.getAnalyticFunction().acceptChildren(v);
217        }
218
219        if (this.getFilterClause() != null){
220            this.getFilterClause().acceptChildren(v);
221        }
222
223        if (this.getWindowDef()  != null){
224            this.getWindowDef().acceptChildren(v);
225        }
226
227        v.postVisit(this);
228
229    }
230}