2020

Texpression Acceptchildren

User should be careful When use acceptChildren() method in the public void preVisit(TExpression node) or public void postVisit(TExpression node) method of your customzied visitor class that extends TParseTreeVisitor.

class TreeVisitor extends TParseTreeVisitor {

    public void preVisit(TExpression node) {
        switch (node.getExpressionType()) {
                case logical_and_t:
                case logical_or_t:
                        node.getLeftOperand().acceptChildren(this);
                        node.getRightOperand().acceptChildren(this);
                    break;
                default:
                    break;        
        }
    }

The above code will cause the left and right sub-expression repeatedly visited, if the expression itself is deeply nested, then the performance will be impacted severely.

Since the acceptChildren() method of TExpression will iterate all sub-expression for you automatically, you shouldn’t call acceptChildren() in the preVisit() method of your own visitor. Only add your business code in the preVisit() method and let the acceptChildren() method of TExpression do the iteration for you.

If you want to iterate all sub-expression in your own code, please use accept() method instead of acceptChildren().

Below is the code of the acceptChildren() method of TExpression for your reference.

    public void acceptChildren(TParseTreeVisitor v){
        v.preVisit(this);
        switch(expressionType){
            case simple_object_name_t:
                objectOperand.acceptChildren(v);
                break;
            case list_t:
            case collection_constructor_list_t:
            case collection_constructor_multiset_t:
            case collection_constructor_set_t:
                if (exprList != null){
                    for(int i=0;i<exprList.size();i++){
                        exprList.getExpression(i).acceptChildren(v);
                    }
                }
                break;
            case function_t:
            case new_structured_type_t:
            case type_constructor_t:
                functionCall.acceptChildren(v);
                break;
            case cursor_t:
            case subquery_t:
            case multiset_t:
                subQuery.acceptChildren(v);
                break;
            case case_t:
                caseExpression.acceptChildren(v);
                break;
            case pattern_matching_t:
                leftOperand.acceptChildren(v);
                rightOperand.acceptChildren(v);
                if (likeEscapeOperand != null){
                    likeEscapeOperand.acceptChildren(v);
                }
                break;
            case exists_t:
                subQuery.acceptChildren(v);
                break;
            case new_variant_type_t:
                newVariantTypeArgumentList.acceptChildren(v);
                break;
            case unary_plus_t:
            case unary_minus_t:
            case unary_prior_t:
                rightOperand.acceptChildren(v);
                break;
            case arithmetic_plus_t:
            case arithmetic_minus_t:
            case arithmetic_times_t:
            case arithmetic_divide_t:
            case power_t:
            case range_t:
            case concatenate_t:
            case period_ldiff_t:
            case period_rdiff_t:
            case period_p_intersect_t:
            case period_p_normalize_t:
            case contains_t:
                leftOperand.acceptChildren(v);
                rightOperand.acceptChildren(v);
                break;
            case assignment_t:
                leftOperand.acceptChildren(v);
                rightOperand.acceptChildren(v);
                break;
            case sqlserver_proprietary_column_alias_t:
                rightOperand.acceptChildren(v);
                break;
            case arithmetic_modulo_t:
            case bitwise_exclusive_or_t:
            case bitwise_or_t:
            case bitwise_and_t:
            case bitwise_xor_t:
            case exponentiate_t:
            case scope_resolution_t:
            case at_time_zone_t:
            case member_of_t:
            case arithmetic_exponentiation_t:
                leftOperand.acceptChildren(v);
                rightOperand.acceptChildren(v);
                break;
            case at_local_t:
            case day_to_second_t:
            case year_to_month_t:
                leftOperand.acceptChildren(v);
                break;
            case parenthesis_t:
                leftOperand.acceptChildren(v);
                break;
            case simple_comparison_t:
                leftOperand.acceptChildren(v);
                rightOperand.acceptChildren(v);
                break;
            case group_comparison_t:
                leftOperand.acceptChildren(v);
                rightOperand.acceptChildren(v);
                break;
            case in_t:
                leftOperand.acceptChildren(v);
                rightOperand.acceptChildren(v);
                break;
            case floating_point_t:
                leftOperand.acceptChildren(v);
                break;
            case logical_and_t:
            case logical_or_t:
            case logical_xor_t:
            case is_t:
                leftOperand.acceptChildren(v);
                rightOperand.acceptChildren(v);
                break;
            case logical_not_t:
                rightOperand.acceptChildren(v);
                break;
            case null_t:
                leftOperand.acceptChildren(v);
                break;
            case between_t:
                if (betweenOperand != null){
                    betweenOperand.acceptChildren(v);
                }
                leftOperand.acceptChildren(v);
                rightOperand.acceptChildren(v);
                break;
            case is_of_type_t:
                leftOperand.acceptChildren(v);
                break;
            case collate_t: //sql server,postgresql
                leftOperand.acceptChildren(v);
                rightOperand.acceptChildren(v);
                break;
            case left_join_t:
            case right_join_t:
                leftOperand.acceptChildren(v);
                rightOperand.acceptChildren(v);
                break;
            case ref_arrow_t:
                leftOperand.acceptChildren(v);
                rightOperand.acceptChildren(v);
                break;
            case typecast_t:
                leftOperand.acceptChildren(v);
                break;
            case arrayaccess_t:
                arrayAccess.acceptChildren(v);
                break;
            case unary_connect_by_root_t:
                rightOperand.acceptChildren(v);
                break;
            case interval_t:
                intervalExpr.acceptChildren(v);
                break;
            case unary_binary_operator_t:
                rightOperand.acceptChildren(v);
                break;
            case left_shift_t:
            case right_shift_t:
                leftOperand.acceptChildren(v);
                rightOperand.acceptChildren(v);
                break;
            case array_constructor_t:
                if (subQuery != null){
                    subQuery.acceptChildren(v);
                }else if (exprList != null){
                    exprList.acceptChildren(v);
                }else if (arrayConstruct != null){
                    arrayConstruct.acceptChildren(v);
                }
                break;
            case row_constructor_t:
                if (exprList != null){
                    exprList.acceptChildren(v);
                }
                break;
            case unary_squareroot_t:
            case unary_cuberoot_t:
            case unary_factorialprefix_t:
            case unary_absolutevalue_t:
            case unary_bitwise_not_t:
                getRightOperand().acceptChildren(v);
                break;
            case unary_factorial_t:
                getLeftOperand().acceptChildren(v);
                break;
            case bitwise_shift_left_t:
            case bitwise_shift_right_t:
                getLeftOperand().acceptChildren(v);
                getRightOperand().acceptChildren(v);
                break;
            case multiset_union_t:
            case multiset_union_distinct_t:
            case multiset_intersect_t:
            case multiset_intersect_distinct_t:
            case multiset_except_t:
            case multiset_except_distinct_t:
                getLeftOperand().acceptChildren(v);
                getRightOperand().acceptChildren(v);
                break;
            case json_get_text:
            case json_get_text_at_path:
            case json_get_object:
            case json_get_object_at_path:
            case json_left_contain:
            case json_right_contain:
            case json_exist:
            case json_any_exist:
            case json_all_exist:
                getLeftOperand().acceptChildren(v);
                getRightOperand().acceptChildren(v);
                break;
            case interpolate_previous_value_t:
                getLeftOperand().acceptChildren(v);
                getRightOperand().acceptChildren(v);
                break;
            case submultiset_t:
                leftOperand.acceptChildren(v);
                rightOperand.acceptChildren(v);
                break;
            case overlaps_t:
                leftOperand.acceptChildren(v);
                rightOperand.acceptChildren(v);
                break;
            case is_a_set_t:
                leftOperand.acceptChildren(v);
                break;
            case array_t:
                if (getExprList() != null){
                    getExprList().acceptChildren(v);
                }
                break;
            default:;
        }

        v.postVisit(this);
    }

Back to Top ↑

2019

Dotnet Parser Throws Exception

General SQL Parser .NET version

We have have confirmed, that the issue appears strictly only with .NET framework 4.6.1586.0, but happens just sometimes.

With the higher .NET framework 4.7.2053.0 all works fine.

2019-10-02 14:02:56,506 ERROR [11] ParserBase:0 Failed to parse vendor MsSql sql string 
CREATE TABLE COPS_ZT (
                                REC_ID     BIGINT IDENTITY NOT NULL,
                                REF_REC_ID BIGINT NOT NULL,
                                REC_DATE DATETIME2 NOT NULL,
                                REC_STATUS       NUMERIC NOT NULL,
                                REC_ERROR        NVARCHAR(255),
                                ZT_CREATION_USER NVARCHAR(255),
                                ZT_CREATION_DATE DATETIME2)
2019-10-02 14:02:56,513 ERROR [11] ParserBase:0 System.ArgumentException: Destination array was not long enough. Check destIndex and length, and the array's lower bounds.
   at System.Array.Copy(Array sourceArray, Int32 sourceIndex, Array destinationArray, Int32 destinationIndex, Int32 length, Boolean reliable)
   at System.Collections.Generic.Dictionary`2.Resize(Int32 newSize, Boolean forceNewHashCodes)
   at System.Collections.Generic.Dictionary`2.Insert(TKey key, TValue value, Boolean add)
   at gudusoft.gsqlparser.nodes.TTypeName.searchTypeByName(String typenameStr)
   at gudusoft.gsqlparser.nodes.TTypeName.set_DataTypeByToken(TSourceToken value)
   at gudusoft.gsqlparser.nodes.TTypeName.setDataTypeInTokens()
   at gudusoft.gsqlparser.TParserMssqlSql.yyaction(Int32 yyruleno)
   at gudusoft.gsqlparser.TParserMssqlSql.yyparse()
   at gudusoft.gsqlparser.TCustomSqlStatement.dochecksyntax(TCustomSqlStatement psql)
   at gudusoft.gsqlparser.TCustomSqlStatement.parsestatement(TCustomSqlStatement pparentsql, Boolean isparsetreeavailable)
   at gudusoft.gsqlparser.TGSqlParser.doparse()
   at CopsDatabasePatcher.SqlParser.SqlParser.Parse(String sql, DatabaseSystem system)
2019-10-02 14:02:56,522 ERROR [11] ParserBase:0 SQL 'CREATE TABLE COPS_ZT (
                                REC_ID     BIGINT IDENTITY NOT NULL,
                                REF_REC_ID BIGINT NOT NULL,
                                REC_DATE DATETIME2 NOT NULL,
                                REC_STATUS       NUMERIC NOT NULL,
                                REC_ERROR        NVARCHAR(255),
                                ZT_CREATION_USER NVARCHAR(255),
                                ZT_CREATION_DATE DATETIME2)' cannot be parsered! Reason 

Code to produce this error:

Back to Top ↑

2018

General SQL Parser Java version 1.9.5.5 released (2018-10-22)

  • GSP Java version 1.9.5.5(2018-10-21)
    • [Oracle] able to recognize and parser noneditionable trigger
    • [Teradata] support at time zone clause of DATE datatype.
    • [Teradata] support with return only clause in declare cursor statement.
    • [SQL Server] support OBJECT:: in grant statement.
    • [SQL Server] support xmlnamespaces clause used together with CTE.

General SQL Parser dotnet version 3.2.7.2 released (2018-10-22)

  • dotnet version 3.2.7.2(2018-10-21)
    • [SQL Server] support NO_PERFORMANCE_SPOOL, MIN_GRANT_PERCENT, HINT_MAX_GRANT_PERCENT
    • [API] add new enum elements: EQueryHint.E_QUERY_HINT_NO_PERFORMANCE_SPOOL, E_QUERY_HINT_MIN_GRANT_PERCENT, E_QUERY_HINT_MAX_GRANT_PERCENT
    • [SQL Server/scriptWriter] support call target expression of function call.
    • [Oracle] able to recognize create or repleace context statement.
    • [DB2] able to link column in call statement to table of create trigger statement.
  • dotnet version 3.2.7.1(2018-10-09)
    • [SQL Server] Doesn’t treat [DATE] as a regular column name.
  • dotnet version 3.2.7.1(2018-10-08)
    • [API] TTypeName.isCharUnit(), TTypeName.ByteUnit is no longer used, replaced by TTypeName.charUnitToken
    • [Oracle] able to get label name after loop/while statement.
    • [Oracle] support on null clause in default clause.
    • [API] add new property: TColumnDefinition.onNull
  • dotnet version 3.2.7.0(2018-10-08)
    • [sql formatter] Able to format subquery or CASE statement inside of CAST function.
  • dotnet version 3.2.6.9(2018-10-03)
    • [API] add new property: TColumnDefinition.persistedColumn.
    • [SQL Server] able to get persisted information from column definition.
    • [API] add new property: TColumnDefinition.filestream.
    • [SQL Server] support FILESTREAM keyword in create table.
    • [API] add new property: TColumnDefinition.sparseColumn.
    • [SQL Server] Able to get SPARSE column information from TColumnDefinition.
  • dotnet version 3.2.6.8(2018-09-28)
    • [MySQL] Able to get comment/KEY_BLOCK_SIZE/parser name index option in MySQL create index statement.
    • [API] TMySQLIndexOption.indexOptionType
    • [API] add new enum: EIndexOptionType
    • [API] add new property : TCreateIndexSqlStatement.IndexOptionList to access index option of MySQL create index statement.
    • [SQL Server] able to fetch include column list from create index statement.

General SQL Parser Java version changelog 2018-08-01

version history of general sql parser:

  • GSP Java version 1.9.4.4(2018-08-22)
    • [API] Add new method TSourceToken TSourceToken.nextSolidToken(boolean treatCommentAsSolidToken)
    • [API] Add new method TSourceToken TSourceToken.prevSolidToken(boolean treatCommentAsSolidToken)

General SQL Parser .NET version changelog 2018-08-01

  • dotnet version 3.2.5.6(2018-08-01)
    • [Oracle] fix a bug can’t parse plsql block not ended by a semicolon.
    • [general] avoid System.ArgumentNullException when call isvalidsqlpluscmd().
  • dotnet version 3.2.5.6(2018-07-27)
    • [scriptWriter] fix a bug when new TObjectName with object and part source token.
    • [API] add new method: TSourceToken.toScript()
Back to Top ↑