001package gudusoft.gsqlparser.stmt;
002
003
004import gudusoft.gsqlparser.*;
005import gudusoft.gsqlparser.compiler.TFrame;
006import gudusoft.gsqlparser.compiler.TVariable;
007import gudusoft.gsqlparser.nodes.*;
008import gudusoft.gsqlparser.nodes.mssql.TProcedureOption;
009import gudusoft.gsqlparser.sqlenv.TSQLFunction;
010import gudusoft.gsqlparser.sqlenv.TSQLTable;
011import gudusoft.gsqlparser.stmt.db2.TDb2ReturnStmt;
012import gudusoft.gsqlparser.stmt.mssql.TMssqlBlock;
013import gudusoft.gsqlparser.stmt.mssql.TMssqlReturn;
014
015/**
016 * Create function.
017 *
018 * Supported database:
019 *
020 * <ul>
021 *     <li>BigQuery</li>
022 * </ul>
023 */
024public class TCreateFunctionStmt extends TRoutine{
025
026    private TMssqlBlock block = null;
027    private TMssqlReturn returnStmt = null;
028    private TPTNodeList <TProcedureOption> procedureOptions;
029    private TObjectName returnTableVaraible = null;
030    private TTableElementList returnTableDefinitions = null;
031    private TTypeName returnDataType = null;
032    private int functionType = TBaseType.uftScalar;
033
034    //  private TObjectName outerLabelName = null;
035    private TConstant objfile;
036    private TConstant linkSymbol;
037
038    private String className;
039    private String resourceType;//jar, file
040    private String resourceURI;//
041    private EFunctionReturnsType returnsType = EFunctionReturnsType.frtScalar;
042
043    //private TTypeName returnDataType = null;
044    private int returnMode = TBaseType.function_return_datatype;
045
046    private TExpression sqlExpression;//bigquery
047    private String sharedLibraryName;
048    private TConstant functionDefinition;
049    private TConstant procedureLanguage;
050
051
052    public void setProcedureOptions(TPTNodeList<TProcedureOption> procedureOptions) {
053        this.procedureOptions = procedureOptions;
054    }
055
056    public TPTNodeList<TProcedureOption> getProcedureOptions() {
057        return procedureOptions;
058    }
059
060
061     // TGSqlParser newParser ;
062//    static int gCount;
063//    static {
064//        //newParser = new TGSqlParser(EDbVendor.dbvpostgresql);
065//        gCount = 0;
066//    }
067    public TCreateFunctionStmt (EDbVendor dbvendor){
068        super(dbvendor);
069        sqlstatementtype = ESqlStatementType.sstcreatefunction ;
070       // newParser = new TGSqlParser(EDbVendor.dbvpostgresql);
071    }
072
073    private TObjectName functionName = null;
074    @Override
075    public TObjectName getStoredProcedureName(){
076        return functionName;
077    }
078    /**
079     * The name that you give to the function that you are declaring or defining.
080     * @return
081     */
082    public TObjectName getFunctionName() {
083        return functionName;
084    }
085
086    public EFunctionReturnsType getReturnsType() {
087        return returnsType;
088    }
089
090    public int getReturnMode() {
091        return returnMode;
092    }
093
094    /**
095     *
096     * @return statements in create function
097     */
098    public TMssqlBlock getBlock() {
099        return block;
100    }
101
102    /**
103     *
104     * @return this is the only return statement in create function.
105     */
106    public TMssqlReturn getReturnStmt() {
107        return returnStmt;
108    }
109
110    public TObjectName getReturnTableVaraible() {
111        return returnTableVaraible;
112    }
113
114    /**
115     * when {@link #getReturnsType()} == {@link EFunctionReturnsType#frtMultiStatementTableValue}
116     * returns this table_type_definition
117     *
118     * @return table_type_definition
119     */
120    public TTableElementList getReturnTableDefinitions() {
121        return returnTableDefinitions;
122    }
123    public TTypeName getReturnDataType() {
124        return returnDataType;
125    }
126
127    /**
128     * this is used for backward compatibility  of .NET version TMssqlCreateFunction.functiontype
129     * please use {@link #returnMode} in java version
130     * @return
131     */
132    public int getFunctionType() {
133        int ret = this.functionType;
134        if (this.returnMode == TBaseType.function_return_table_variable){
135            ret = TBaseType.uftMultiStatementTableValued;
136        }else if (this.returnMode == TBaseType.function_return_table){
137            ret = TBaseType.uftInlineTableValued;
138        }
139        return ret;
140    }
141
142    public TConstant getObjfile() {
143        return objfile;
144    }
145    public TConstant getLinkSymbol() {
146        return linkSymbol;
147    }
148    public String getClassName() {
149        return className;
150    }
151    public String getResourceType() {
152        return resourceType;
153    }
154    public String getResourceURI() {
155        return resourceURI;
156    }
157
158    public void setSqlExpression(TExpression sqlExpression) {
159        this.sqlExpression = sqlExpression;
160    }
161    public TExpression getSqlExpression() {
162        return sqlExpression;
163    }
164    public String getSharedLibraryName() {
165        return sharedLibraryName;
166    }
167    public TConstant getFunctionDefinition() {
168        return functionDefinition;
169    }
170    public TConstant getProcedureLanguage() {
171        return procedureLanguage;
172    }
173
174
175    private void redshiftFunctionDefinition(TCustomSqlStatement psql,TCreateFunctionSqlNode createFunctionNode){
176        language = TRoutine.LANGUAGE_UNKNOWN;
177        if ((createFunctionNode.getFunctionBody() != null)&&(getProcedureLanguage().toString().equalsIgnoreCase("sql"))){
178            language = TRoutine.LANGUAGE_SQL;
179            String bodyStr  = createFunctionNode.getFunctionBody().getStartToken().getQuotedString();//.trim();
180            if (createFunctionNode.getFunctionBody().getStartToken().toString().startsWith("'")){
181                bodyStr = bodyStr.replaceAll("''","'");
182            }
183
184
185            //System.out.println(bodyStr);
186            int testLen = 9;
187            if (bodyStr.trim().length() < testLen) testLen = bodyStr.trim().length();
188
189            String prefixStr = bodyStr.trim().substring(0,testLen).toLowerCase();
190            boolean isExpression = true;
191            TGSqlParser newParser = new TGSqlParser(this.dbvendor);
192
193            newParser.sqltext =
194                    TBaseType.stringBlock(
195                            (int)createFunctionNode.getFunctionBody().getStartToken().lineNo - 1,
196                            (int)createFunctionNode.getFunctionBody().getStartToken().columnNo + createFunctionNode.getFunctionBody().getStartToken().getQuoteSymbolLength()-1
197                    )
198                    + bodyStr;
199
200            newParser.setFrameStack(getFrameStack());
201            int iRet = newParser.parse();
202            if ((iRet == 0)&&(newParser.getSqlstatements().size() >0)){
203//                this.blockBody = new TBlockSqlNode();
204//                this.blockBody.setParsed(true);
205//                this.blockBody.getBodyStatements().add(newParser.getSqlstatements().get(0));
206
207               this.getBodyStatements().add(newParser.getSqlstatements().get(0));
208            }else {
209                for(int j=0;j<newParser.getErrorCount();j++){
210                    this.parseerrormessagehandle(newParser.getSyntaxErrors().get(j));
211                }
212            }
213        }
214
215    }
216
217    private void postgresqlFunctionDefinition(TCustomSqlStatement psql,TCreateFunctionSqlNode createFunctionNode){
218        language =  TRoutine.LANGUAGE_UNKNOWN;
219        if ((createFunctionNode.getFunctionBody() != null)&&(getProcedureLanguage()!=null)&&(getProcedureLanguage().toString() !=null)) {
220            if (getProcedureLanguage().toString().equalsIgnoreCase("sql")) language = TRoutine.LANGUAGE_SQL;
221            else if (getProcedureLanguage().toString().equalsIgnoreCase("plpgsql")) language = TRoutine.LANGUAGE_PLPGSQL;
222            else if (getProcedureLanguage().toString().equalsIgnoreCase("'plpgsql'")) language = TRoutine.LANGUAGE_PLPGSQL;
223
224            if ((language == TRoutine.LANGUAGE_SQL)||(language == TRoutine.LANGUAGE_PLPGSQL))
225            {
226
227                String bodyStr = createFunctionNode.getFunctionBody().getStartToken().getQuotedString();//.trim();
228                // System.out.println(bodyStr);
229                //long lineNo = createFunctionNode.getFunctionBody().getStartToken().lineNo ;
230                // CREATE OR REPLACE FUNCTION testspg__getString (varchar) RETURNS varchar as ' DECLARE inString alias for $1; begin return ''bob''; end; ' LANGUAGE plpgsql
231                // escaped quotes in string literals
232                // mantisbt/view.php?id=1331
233                if (createFunctionNode.getFunctionBody().getStartToken().toString().startsWith("'")) {
234                    bodyStr = bodyStr.replaceAll("''", "'");
235                }
236
237
238                // System.out.println(bodyStr);
239                //String prefixStr = bodyStr.trim().substring(0, (bodyStr.trim().length() < 9 ? bodyStr.trim().length() : 9)).toLowerCase();
240                //String suffixStr = bodyStr.trim().length() <= 7 ? bodyStr.trim() : bodyStr.trim().substring(bodyStr.trim().length() - 7);
241                                
242                String bodyStrTrim = bodyStr.trim();
243                int bodyStringLength = bodyStrTrim.length();
244                String prefixStr = bodyStringLength <= 7 ? bodyStrTrim.toLowerCase() : bodyStrTrim.substring(0, 7).toLowerCase();
245                String suffixStr = bodyStringLength <= 7 ? prefixStr : bodyStrTrim.substring(bodyStringLength - 7).toLowerCase();
246                                
247                boolean isSQLBlock = true;
248                TGSqlParser newParser = new TGSqlParser(EDbVendor.dbvpostgresql);
249                if ((prefixStr.startsWith("declare")) || (prefixStr.startsWith("begin")) || (prefixStr.startsWith("<<"))
250                        // || (((suffixStr.toLowerCase().endsWith("end")) || (suffixStr.toLowerCase().endsWith("end;")))&&((!prefixStr.startsWith("select"))))
251                                                   || (((suffixStr.endsWith("end")) || (suffixStr.endsWith("end;")))&&((!prefixStr.startsWith("select"))))
252                ) {
253                    //bodyStr.replaceAll("''","'");
254                    //System.out.println(bodyStr);
255
256                    newParser.sqltext = "plpgsql_function_delimiter\n"
257                            + TBaseType.stringBlock((int) createFunctionNode.getFunctionBody().getStartToken().lineNo - 2, (int) createFunctionNode.getFunctionBody().getStartToken().columnNo + createFunctionNode.getFunctionBody().getStartToken().getQuoteSymbolLength() - 1)
258                            + bodyStr;
259                } else {
260                    newParser.sqltext =
261                            TBaseType.stringBlock(
262                                    (int) createFunctionNode.getFunctionBody().getStartToken().lineNo - 1,
263                                    (int) createFunctionNode.getFunctionBody().getStartToken().columnNo + createFunctionNode.getFunctionBody().getStartToken().getQuoteSymbolLength() - 1)
264                                    + bodyStr;
265                    isSQLBlock = false;
266                }
267
268                newParser.setFrameStack(getFrameStack());
269                // we only need a raw parse tree
270                // newParser.setOnlyNeedRawParseTree(true);
271                int iRet = newParser.parse();
272                if ((iRet == 0) && (newParser.getSqlstatements().size() > 0)) {
273                    if (isSQLBlock) {
274                        TCommonBlock lcBlock = (TCommonBlock) newParser.getSqlstatements().get(0);
275                        this.blockBody = lcBlock.getBlockBody();
276                        this.blockBody.setParent(this);
277
278
279//                        this.setOuterLabelName(lcBlock.getLabelName());
280//                        for(int i=0;i<lcBlock.getDeclareStatements().size();i++){
281//                            this.getTopStatement().getSymbolTable().push( new TSymbolTableItem(TObjectName.ttobjVariable,this,lcBlock.getDeclareStatements().get(i)));
282//                            this.getDeclareStatements().add(lcBlock.getDeclareStatements().get(i));
283//                        }
284//                        for(int i=0;i<lcBlock.getBodyStatements().size();i++){
285//                            lcBlock.getBodyStatements().get(i).setAlreadyAddToParent(false);
286//                            lcBlock.getBodyStatements().get(i).setParentStmt(this);
287//                            //commonBlock.getBodyStatements().get(i).doParseStatement(this);
288//                            this.getBodyStatements().add(lcBlock.getBodyStatements().get(i));
289//                        }
290//                        if (lcBlock.getExceptionClause() != null){
291//                            this.setExceptionClause(lcBlock.getExceptionClause());
292//                        }
293//                        for(int i=0;i<lcBlock.getDeclareStatements().size();i++){
294//                            this.getTopStatement().getSymbolTable().pop();
295//                        }
296                    }else{
297                        this.getBodyStatements().add(newParser.getSqlstatements().get(0));
298//                        TStatementListSqlNode lcStmts = new TStatementListSqlNode();
299//                        TStatementSqlNode lcSqlNode = new TStatementSqlNode();
300//                        lcSqlNode.setSqlNode(newParser.getSqlstatements().get(0).rootNode);
301//                        lcStmts.addStatementSqlNode(lcSqlNode);
302//                        this.blockBody = new TBlockSqlNode();
303//                        this.blockBody.init(lcStmts);
304                    }
305                } else {
306                        for (int j = 0; j < newParser.getErrorCount(); j++) {
307                            this.parseerrormessagehandle(newParser.getSyntaxErrors().get(j));
308                        }
309                }
310
311                }
312            }
313
314    }
315
316    private void snowflakeFunctionDefinition(TCustomSqlStatement psql,TCreateFunctionSqlNode createFunctionNode){
317        language = TRoutine.LANGUAGE_UNKNOWN;
318        if ((createFunctionNode.getFunctionBody() != null)
319                &&((getProcedureLanguage()==null)||((getProcedureLanguage()!=null)&&(getProcedureLanguage().toString().equalsIgnoreCase("SQL"))))){
320                language = TRoutine.LANGUAGE_SQL;
321                String bodyStr  = createFunctionNode.getFunctionBody().getStartToken().getQuotedString();//.trim();
322                // CREATE OR REPLACE FUNCTION testspg__getString (varchar) RETURNS varchar as ' DECLARE inString alias for $1; begin return ''bob''; end; ' LANGUAGE plpgsql
323                // escaped quotes in string literals
324                // mantisbt/view.php?id=1331
325                if (createFunctionNode.getFunctionBody().getStartToken().toString().startsWith("'")){
326                    bodyStr = bodyStr.replaceAll("''","'");
327                }
328
329                //System.out.println(bodyStr);
330                int testLen = 9;
331                if (bodyStr.trim().length() < testLen) testLen = bodyStr.trim().length();
332                String prefixStr = bodyStr.trim().substring(0,testLen).toLowerCase();
333                boolean isExpression = true;
334                TGSqlParser newParser = new TGSqlParser(this.dbvendor);
335                if ((prefixStr.startsWith("select"))||(prefixStr.startsWith("insert"))||(prefixStr.startsWith("delete"))||(prefixStr.startsWith("update"))){
336                    newParser.sqltext =
337                            TBaseType.stringBlock(
338                                    (int)createFunctionNode.getFunctionBody().getStartToken().lineNo - 1,
339                                    (int)createFunctionNode.getFunctionBody().getStartToken().columnNo + createFunctionNode.getFunctionBody().getStartToken().getQuoteSymbolLength()-1)
340                                + bodyStr;
341
342                    isExpression = false;
343                }else{
344                    newParser.sqltext = "pseudo_expr_sign\n"+
345                             TBaseType.stringBlock((int)createFunctionNode.getFunctionBody().getStartToken().lineNo - 2
346                            ,(int)createFunctionNode.getFunctionBody().getStartToken().columnNo+ createFunctionNode.getFunctionBody().getStartToken().getQuoteSymbolLength()-1)
347                            +bodyStr;
348                }
349
350                newParser.setFrameStack(getFrameStack());
351                int iRet = newParser.parse();
352                if ((iRet == 0)&&(newParser.getSqlstatements().size() >0)){
353                    this.getBodyStatements().add(newParser.getSqlstatements().get(0));
354                }else {
355                    for(int j=0;j<newParser.getErrorCount();j++){
356                        this.parseerrormessagehandle(newParser.getSyntaxErrors().get(j));
357                    }
358                }
359        }
360
361    }
362
363    private TSelectSqlStatement sqlQuery;
364
365    public TSelectSqlStatement getSqlQuery() {
366        return sqlQuery;
367    }
368
369    public int doParseStatement(TCustomSqlStatement psql) {
370        if (rootNode == null) return -1;
371        TCreateFunctionSqlNode createFunctionNode = (TCreateFunctionSqlNode)rootNode;
372        if (dbvendor == EDbVendor.dbvpostgresql){
373            if (super.doParseStatement(psql) != 0) return -1;
374        }else
375            super.doParseStatement(psql);
376
377        TFrame currentFrame = new TFrame(this.stmtScope);
378        currentFrame.pushMeToStack(getFrameStack());
379
380        functionName = createFunctionNode.getFunctionName();
381
382        if (getSqlEnv() != null) {
383            getSqlEnv().addFunction(functionName,true);
384
385            // move to TDatabaseObjectResolver
386
387//            if (getSqlEnv().getDefaultCatalogName() != null){
388//                if (functionName.getDatabaseToken() == null){
389//                    functionName.setDatabaseToken(new TSourceToken(getSqlEnv().getDefaultCatalogName()));
390//                }
391//            }
392        }
393
394        // sql server
395        procedureOptions = createFunctionNode.getProcedureOptions();
396        //end sql server
397
398        if (createFunctionNode.getProcedureLanguage() != null){
399            // language name is retrieved through parser
400            procedureLanguage = createFunctionNode.getProcedureLanguage();
401            setRoutineBodyInConstant(procedureLanguage);
402            setRoutineLanguage(procedureLanguage.toString());
403        }else if (getRoutineLanguage() != null){
404            // language name is retrieved during TGsqlParser.dopostgresqlgetrawsqlstatements()
405        }
406
407//        procedureLanguage = createFunctionNode.getProcedureLanguage();
408//        if (procedureLanguage != null){
409//            setRoutineBodyInConstant(procedureLanguage);
410//            setRoutineLanguage(procedureLanguage.toString());
411//        }
412//
413//        // postgresql
414//        procedureLanguage = createFunctionNode.getProcedureLanguage();
415//        if (getRoutineLanguage() == null){
416//            // not already set during TGsqlParser.dopostgresqlgetrawsqlstatements()
417//            // then we set it here
418//            if (procedureLanguage != null){
419//                setRoutineLanguage(procedureLanguage.toString());
420//            }
421//        }
422
423        //outerLabelName = createFunctionNode.getLabelName();
424        objfile = createFunctionNode.getObjfile();
425        linkSymbol = createFunctionNode.getLinkSymbol();
426        this.className = createFunctionNode.getClassName();
427        this.resourceType = createFunctionNode.getResourceType();
428        this.resourceURI = createFunctionNode.getResourceURI();
429
430
431        if (createFunctionNode.getReturnDataType() != null){
432            this.returnMode = TBaseType.function_return_datatype;
433            this.returnDataType = createFunctionNode.getReturnDataType();
434        }else if (createFunctionNode.getReturnTable() != null){
435            TDummy dmy = createFunctionNode.getReturnTable();
436            this.returnMode = TBaseType.function_return_table;
437            if (dmy.list1 instanceof TTableElementList){ // hana includes TParameterDeclarationList type which is not this type
438                this.returnTableDefinitions = (TTableElementList)dmy.list1;
439                this.returnTableDefinitions.doParse(this,ESqlClause.unknown);
440            }
441        }
442        // end of postgresql
443
444        this.setParameterDeclarations(createFunctionNode.getParameters());
445
446        // sql server
447        if (createFunctionNode.getReturnDataType() != null){
448            this.returnMode = TBaseType.function_return_datatype;
449            this.returnDataType = createFunctionNode.getReturnDataType();
450            this.returnsType = EFunctionReturnsType.frtScalar;
451        }else if (createFunctionNode.getReturnTable() != null){
452            TDummy dmy = createFunctionNode.getReturnTable();
453            if (dmy.node1 != null){
454                this.returnsType = EFunctionReturnsType.frtMultiStatementTableValue;
455                this.returnMode = TBaseType.function_return_table_variable;
456                this.returnTableVaraible = (TObjectName)dmy.node1;
457                this.returnTableVaraible.setObjectType(TObjectName.ttobjVariable);
458                this.returnTableDefinitions = (TTableElementList)dmy.list1;
459                this.returnTableDefinitions.doParse(this,ESqlClause.unknown);
460
461                if (getSqlEnv() != null)  {
462                    TSQLTable returnTable = getSqlEnv().addTable(this.returnTableVaraible.toString(),true);
463                    //TSQLFunction functionTable = getSqlEnv().searchFunction(functionName.toString());
464                    TSQLFunction functionTable = getSqlEnv().searchFunction(functionName);
465
466                    if (functionTable == null){
467                        TBaseType.log(String.format("Table function: <%s> is not found in SQL Evn", functionName.toString()),TLog.WARNING,functionName);
468                        //System.out.println("Function not found:"+functionName.toString());
469                        //System.out.println(getSqlEnv().toString());
470                    }
471
472                    for(TTableElement column: this.returnTableDefinitions){
473                        if(column.getColumnDefinition()!=null && column.getColumnDefinition().getColumnName()!=null){
474                            returnTable.addColumn(column.getColumnDefinition().getColumnName().toString());
475                            functionTable.addReturnColumn(column.getColumnDefinition().getColumnName().toString());
476                        }
477                    }
478                }
479            }else{
480                this.returnMode = TBaseType.function_return_table;
481                this.returnsType = EFunctionReturnsType.frtInlineTableValue;
482            }
483        }
484        // end sql server
485
486        // push parameterDeclarations into symbolTable
487        if (this.getParameterDeclarations() != null){
488            for(int i=0;i< this.getParameterDeclarations().size();i++){
489                this.getTopStatement().getSymbolTable().push( new TSymbolTableItem(TObjectName.ttobjParameter,this, this.getParameterDeclarations().getParameterDeclarationItem(i)));
490                TParameterDeclaration parameterDeclaration = this.getParameterDeclarations().getParameterDeclarationItem(i);
491                if (parameterDeclaration.getParameterName() != null){
492                    this.stmtScope.addSymbol(new TVariable(parameterDeclaration.getParameterName(),parameterDeclaration,functionName));
493                }
494            }
495        }
496
497
498        switch (this.dbvendor){
499            case dbvsnowflake:
500                if (createFunctionNode.getBlcok() != null){
501                    // $$ body $$ 在这里处理
502                    createFunctionNode.getBlcok().doParse(this,ESqlClause.unknown);
503                    this.blockBody = createFunctionNode.getBlcok();
504                }else  {
505                    // 'body' 在这里处理
506                    snowflakeFunctionDefinition(psql,createFunctionNode);
507                }
508
509                break;
510            case dbvpostgresql:
511            case dbvgreenplum:
512            case dbvredshift:
513                if (createFunctionNode.getFunctionBody() != null){
514                    // function body only inside '' will be processed here
515                    postgresqlFunctionDefinition(psql,createFunctionNode);
516                }else{
517                    // function body only inside $$ will be processed here
518
519                    if (createFunctionNode.getBlcok() != null){
520                        createFunctionNode.getBlcok().doParse(this,ESqlClause.unknown);
521                        this.blockBody = createFunctionNode.getBlcok();
522                    }else  if (createFunctionNode.getStmt() != null){
523                        createFunctionNode.getStmt().doParse(this, ESqlClause.unknown);
524                        this.getBodyStatements().add(createFunctionNode.getStmt().getStmt());
525                    }else {
526                        // there is no function body is language is not in sql or plsql,
527                        // such as LANGUAGE plpython3u
528                    }
529                }
530                break;
531//            case dbvgreenplum:
532//                postgresqlFunctionDefinition(psql,createFunctionNode);
533//                break;
534            case dbvmssql:
535                if (createFunctionNode.getBlcok() != null){
536                    block = new TMssqlBlock(this.dbvendor);
537                    block.rootNode = createFunctionNode.getBlcok();
538                    block.doParseStatement(this);
539                    this.getBodyStatements().add(block);
540                }
541
542                if (createFunctionNode.getReturnSqlNode() != null){
543                    returnStmt = new TMssqlReturn(this.dbvendor);
544                    returnStmt.rootNode = createFunctionNode.getReturnSqlNode();
545                    returnStmt.doParseStatement(this);
546                    this.getBodyStatements().add(returnStmt);
547                }
548
549                break;
550            case dbvmysql:
551                if (createFunctionNode.getStmt() != null){
552                    createFunctionNode.getStmt().doParse(this,ESqlClause.unknown);
553                    this.getBodyStatements().add(createFunctionNode.getStmt().getStmt());
554                }
555                else if (createFunctionNode.getBlcok() != null){
556                    createFunctionNode.getBlcok().getStmts().doParse(this,ESqlClause.unknown);
557
558                    for(int i=0;i<createFunctionNode.getBlcok().getStmts().size();i++){
559                        this.getBodyStatements().add(createFunctionNode.getBlcok().getStmts().getStatementSqlNode(i).getStmt());
560                    }
561                }
562                break;
563            case dbvbigquery:
564                if (createFunctionNode.getSqlQuery() != null){
565                    sqlQuery = new TSelectSqlStatement(this.dbvendor);
566                    sqlQuery.rootNode = createFunctionNode.getSqlQuery();
567                    sqlQuery.doParseStatement(this);
568                    this.returnMode = TBaseType.function_return_datatype;
569                    this.returnDataType = createFunctionNode.getReturnDataType();
570                    this.returnsType = EFunctionReturnsType.frtInlineTableValue;
571                    this.getBodyStatements().add(sqlQuery);
572                }
573                break;
574            case dbvdb2:
575                TCompoundSqlNode compoundSqlNode = createFunctionNode.getCompoundSql();
576               // TReturnSqlNode returnSqlNode = createFunctionNode.getReturnSqlNode();
577
578                if (compoundSqlNode != null){
579                    if (compoundSqlNode.getDeclareStmts() != null){
580                        compoundSqlNode.getDeclareStmts().doParse(this,ESqlClause.unknown);
581
582                        // push variable declare into symbolTable, and add to declareStatements
583                        for(int i=0;i<compoundSqlNode.getDeclareStmts().size();i++){
584                            this.getTopStatement().getSymbolTable().push( new TSymbolTableItem(TObjectName.ttobjVariable,this,compoundSqlNode.getDeclareStmts().getStatementSqlNode(i).getStmt() ));
585                            this.getDeclareStatements().add(compoundSqlNode.getDeclareStmts().getStatementSqlNode(i).getStmt());
586                        }
587                    }
588
589                    if (compoundSqlNode.getStmts() != null){
590                        compoundSqlNode.getStmts().doParse(this,ESqlClause.unknown);
591
592                        for(int i= 0; i<compoundSqlNode.getStmts().size();i++){
593                            this.getBodyStatements().add(compoundSqlNode.getStmts().getStatementSqlNode(i).getStmt());
594                        }
595                    }
596
597                    if (compoundSqlNode.getDeclareStmts() != null){
598                        // pop variable declare from symbolTable
599                        for(int i=0;i<compoundSqlNode.getDeclareStmts().size();i++){
600                            this.getTopStatement().getSymbolTable().pop();
601                        }
602                    }
603                }else if (createFunctionNode.getReturnSqlNode() != null){
604                    returnStmt = new TMssqlReturn(this.dbvendor);
605                    returnStmt.rootNode = createFunctionNode.getReturnSqlNode();
606                    returnStmt.doParseStatement(this);
607                    this.getBodyStatements().add(returnStmt);
608                }
609
610                break;
611            default:
612                if (createFunctionNode.getStmt() != null){
613                    createFunctionNode.getStmt().doParse(this, ESqlClause.unknown);
614                    this.getBodyStatements().add(createFunctionNode.getStmt().getStmt());
615//                    TStatementListSqlNode lcStmts = new TStatementListSqlNode();
616//                    lcStmts.addStatementSqlNode(createFunctionNode.getStmt());
617//                    this.blockBody = new TBlockSqlNode();
618//                    this.blockBody.init(lcStmts);
619                }
620                else if (createFunctionNode.getBlcok() != null){
621                    createFunctionNode.getBlcok().doParse(this,ESqlClause.unknown);
622                    //createFunctionNode.getBlcok().getStmts().doParse(this,ESqlClause.unknown);
623//
624//                    for(int i=0;i<createFunctionNode.getBlcok().getStmts().size();i++){
625//                        this.getBodyStatements().add(createFunctionNode.getBlcok().getStmts().getStatementSqlNode(i).getStmt());
626//                    }
627                    this.blockBody = createFunctionNode.getBlcok();
628                }
629                break;
630        }
631
632
633
634
635        // pop parameterDeclarations from symbolTable
636        if (this.getParameterDeclarations() != null){
637            for(int i=0;i< this.getParameterDeclarations().size();i++){
638                this.getTopStatement().getSymbolTable().pop();
639            }
640        }
641
642        if (createFunctionNode.getSharedLibraryName() != null){
643            sharedLibraryName = createFunctionNode.getSharedLibraryName().toString();
644        }
645
646        functionDefinition  = createFunctionNode.getFunctionDefinition();
647        if (functionDefinition != null){
648            setRoutineBodyInConstant(functionDefinition);
649            setRoutineBody(functionDefinition.toString());
650        }
651
652        this.sqlExpression = createFunctionNode.getSqlExpression();
653        if (this.sqlExpression != null){
654            this.sqlExpression.doParse(this,ESqlClause.unknown);
655        }
656
657        //endlabelName = createFunctionNode.getEndlabelName();
658        currentFrame.popMeFromStack(getFrameStack());
659
660        return 0;
661    }
662
663    public void accept(TParseTreeVisitor v){
664        v.preVisit(this);
665        v.postVisit(this);
666    }
667
668    public void acceptChildren(TParseTreeVisitor v){
669        v.preVisit(this);
670        this.getFunctionName().acceptChildren(v);
671        if (getParameterDeclarations() != null) getParameterDeclarations().acceptChildren(v);
672        if (blockBody != null){
673            blockBody.acceptChildren(v);
674        }else if (getBodyStatements().size() > 0){
675            getBodyStatements().acceptChildren(v);
676        }
677        if (returnStmt != null) returnStmt.acceptChildren(v);
678        v.postVisit(this);
679    }
680
681
682    public void setFunctionName(TObjectName functionName) {
683        this.functionName = functionName;
684    }
685
686    public void setBlock(TMssqlBlock block) {
687        this.block = block;
688    }
689    public void setReturnStmt(TMssqlReturn returnStmt) {
690        this.returnStmt = returnStmt;
691    }
692    public void setReturnMode(int returnMode) {
693        this.returnMode = returnMode;
694    }
695    public void setReturnTableVaraible(TObjectName returnTableVaraible) {
696        this.returnTableVaraible = returnTableVaraible;
697    }
698    public void setReturnTableDefinitions(TTableElementList returnTableDefinitions) {
699        this.returnTableDefinitions = returnTableDefinitions;
700    }
701    public void setReturnDataType(TTypeName returnDataType) {
702        this.returnDataType = returnDataType;
703    }
704    public void setFunctionType(int functionType) {
705        this.functionType = functionType;
706    }
707
708}