Class TParseTreeNode

Object
gudusoft.gsqlparser.nodes.TParseTreeNode
All Implemented Interfaces:
Visitable, Iterator<TSourceToken>
Direct Known Subclasses:
TAbortSqlNode, TAliasClause, TAlterAccessPolicySqlNode, TAlterAuthenticationSqlNode, TAlterDatabaseSqlNode, TAlterFaultGroupSqlNode, TAlterFunctionSqlNode, TAlterIndexSqlNode, TAlterLibrarySqlNode, TAlterNodeSqlNode, TAlterPartitionFunctionSqlNode, TAlterPartitionSchemeSqlNode, TAlterProcedureSqlNode, TAlterRoleSqlNode, TAlterSchemaSqlNode, TAlterSequenceSqlNode, TAlterSessionSqlNode, TAlterTableOption, TAlterTableSqlNode, TAlterTriggerSqlNode, TAlterTypeOption, TAlterTypeSqlNode, TAlterViewSqlNode, TAnalyticFunction, TAnalyzeSqlNode, TArrayAccess, TArrayConstruct, TAtBeforeClause, TAttributeOption, TAttributeOrMethod, TAuthorizationClause, TAutomaticProperty, TBaseTablePartition, TBeginTranSqlNode, TBindArgument, TBinding, TBreakSqlNode, TBuildIndexesSqlNode, TCallSpec, TCallSqlNode, TCaseExpression, TCaseJoinClause, TCaseJoinItem, TCharacterDatatypeProperty, TCloseSqlNode, TClusterBy, TCollectColumnIndex, TCollectFromOption, TCollectStatisticsSqlNode, TColumnAttribute, TColumnDefinition, TColumnGeneratedClause, TColumnReference, TColumnStorage, TColumnWithSortOrder, TCommentSqlNode, TCommitSqlNode, TCompoundSqlNode, TCompoundTriggerBodyNode, TComputeClause, TComputeClauseItem, TComputeExpr, TConnectByClause, TConnectSqlNode, TConstant, TConstraint, TConstructorBody, TConstructorSpec, TContainsTable, TContinueSqlNode, TCopyIntoNode, TCopyIntoSqlNode, TCopySqlNode, TCreateAccessPolicySqlNode, TCreateDatabaseSqlNode, TCreateDirectorySqlNode, TCreateFunctionOption, TCreateFunctionSqlNode, TCreateIndexSqlNode, TCreateMacroSqlNode, TCreateMaterializedViewLogSqlNode, TCreateMaterializedViewSqlNode, TCreateModelSqlNode, TCreatePackageSqlNode, TCreatePartitionFunctionSqlNode, TCreatePartitionSchemeSqlNode, TCreatePipeSqlNode, TCreateProcedureSqlNode, TCreateRoleSqlNode, TCreateRowTypeSqlNode, TCreateSchemaSqlNode, TCreateSecurityPolicySqlNode, TCreateSemanticViewSqlNode, TCreateSequenceSqlNode, TCreateStageSqlNode, TCreateStreamSqlNode, TCreateSynonymSqlNode, TCreateTableOption, TCreateTableSqlNode, TCreateTaskSqlNode, TCreateTriggerSqlNode, TCreateTypeSqlNode, TCreateUserSqlNode, TCreateViewSqlNode, TCustomForXMLItem, TCustomSqlStatement, TDataChangeTable, TDataConversion, TDataConversionItem, TDataDefinition, TDatatypeAttribute, TDatetimeExpression, TDaxExprPair, TDaxNameExpression, TDaxOrderByExpr, TDaxVar, TDeallocatePrepareSqlNode, TDeclareSqlNode, TDeclareVariable, TDeleteSqlNode, TDeleteStatisticsSqlNode, TDescribeSqlNode, TDisableEnableTriggerSqlNode, TDistributeBy, TDoExecuteBlockSqlNode, TDropDatabaseSqlNode, TDropDbObjectSqlNode, TDropFunctionSqlNode, TDropIndexItem, TDropIndexSqlNode, TDropProcedureSqlNode, TDropSchemaSqlNode, TDropSequenceSqlNode, TDropTableSqlNode, TDropViewSqlNode, TDummy, TElseIfSqlNode, TEndTranSqlNode, TErrorLoggingClause, TExceptionClause, TExceptionHandler, TExceptReplaceClause, TExecImmeNode, TExecParameter, TExecuteAsClause, TExecuteAsSqlNode, TExecuteOption, TExecuteSqlNode, TExpandOnClause, TExplicitDataTypeConversion, TExportDataSqlNode, TExportToVerticaSqlNode, TExpression, TExpressionCallTarget, TExternalTableOption, TFetchFirstClause, TFetchSqlNode, TFileFormatSqlNode, TFlashback, TForSqlNode, TForUpdate, TForXMLClause, TFrameExclusionClause, TFunctionCall, TFunctionHeader, TGenerateStatisticsSqlNode, TGetDiagSqlNode, TGrantSqlNode, TGroomTableSqlNode, TGroupBy, TGroupByItem, TGroupConcatParam, TGroupingExpressionItem, TGroupingSet, TGroupingSetItem, THandlerForCondition, THashByClause, THavingClause, THierarchical, THintClause, THiveCreateRoleSqlNode, THiveDescribeSqlNode, THiveDescTablePartition, THiveDescTabType, THiveDropDBSqlNode, THiveDropFunctionSqlNode, THiveDropRoleSqlNode, THiveExplainSqlNode, THiveExportSqlNode, THiveFromQuerySqlNode, THiveGrantRoleSqlNode, THiveGrantSqlNode, THiveHintClause, THiveHintItem, THiveImportSqlNode, THiveIndexProperties, THiveKeyValueProperty, THiveLoadSqlNode, THivePartitionedTableFunction, THivePrincipalName, THivePrivilegeDef, THiveRecordReader, THiveRecordWriter, THiveRowFormat, THiveShowGrantSqlNode, THiveShowRoleGrantSqlNode, THiveShowSqlNode, THiveSwitchDBSqlNode, THiveTableBuckets, THiveTableFileFormat, THiveTablePartition, THiveTableProperties, THiveTableSkewed, THiveTerminatedIdentifier, THiveTransformClause, THiveVariable, THiveWithDBPropertiesClause, TIdentityClause, TIfSqlNode, TIncludeColumns, TIndexColName, TIndexDefinition, TIndexKeyTerm, TIndexRef, TIndices, TIndirection, TInExpr, TInferKeyspaceSqlNode, TInformixOuterClause, TInheritsClause, TInsertBulkSqlNode, TInsertCondition, TInsertIntoValue, TInsertSqlNode, TIntervalExpression, TIntoClause, TIntoTableClause, TInvokerRightsClause, TIsolationClause, TIterateSqlNode, TJoinItem, TJsonObjectKeyValue, TKeepDenseRankClause, TKeyAction, TKeyReference, TKeyspaceRef, TKeyValueSqlNode, TLateralView, TLeaveSqlNode, TLimitClause, TListaggOverflow, TListSubpartitionDesc, TListValuesClause, TLockingClause, TLockSqlNode, TMaterializedViewProps, TMdxAlterCubeNode, TMdxAxis, TMdxCalcPropNode, TMdxCallNode, TMdxCreateMeasureNode, TMdxCreateMemberNode, TMdxCreateSessionCubeNode, TMdxCreateSetNode, TMdxCreateSubCubeNode, TMdxDimContentNode, TMdxDrillthroughNode, TMdxExpNode, TMdxKeySegment, TMdxLevelContentNode, TMdxNameSegment, TMdxObjectNode, TMdxScopeNode, TMdxSelectNode, TMdxWhereNode, TMdxWithNode, TMergeActionClause, TMergeSqlNode, TMergeWhenClause, TModeChoice, TMoveSqlNode, TMSCKSqlNode, TMssqlBeginConversationTimerSqlNode, TMssqlBeginDialogSqlNode, TMssqlBulkInsertSqlNode, TMssqlCreateTriggerUpdateColumn, TMssqlCreateTypeSqlNode, TMssqlCreateXmlSchemaCollectionSqlNode, TMssqlDeallocateSqlNode, TMssqlEndConversationSqlNode, TMssqlGotoSqlNode, TMssqlLabelSqlNode, TMssqlRaiserrorSqlNode, TMssqlReconfigureSqlNode, TMssqlRevertSqlNode, TMssqlSendOnConversationSqlNode, TMssqlSetSqlNode, TMssqlStmtStubSqlNode, TMssqlThrowSqlNode, TMssqlUpdateTextSqlNode, TMultiTarget, TMySQLCreateTableOption, TMySQLIndexOption, TMySQLIndexStorageType, TNameValuePair, TNewVariantTypeArgument, TNodeWithAliasClause, TNodeWithLabel, TNullSqlNode, TObjectAccess, TObjectConstruct, TObjectName, TObjectReference, TOffsetClause, TOpenDatasource, TOpenQuery, TOpenRowSet, TOpenSqlNode, TOpenXML, TOptimizeForClause, TOptionClause, TOracleBuildClause, TOracleCacheClause, TOracleCreateLibrarySqlNode, TOracleCreateMvRefresh, TOracleCreateMvRefreshOption, TOracleLoggingClause, TOracleParallelClause, TOracleUsingIndex, TOrderBy, TOrderByItem, TOutputClause, TOutputFormatPhrase, TPair, TParallelEnableClause, TParameterDeclaration, TParameterMode, TParseErrorSqlNode, TParseTreeNodeList, TPartitionBoundSpecSqlNode, TPartitionByClause, TPartitionClause, TPartitionDefinition, TPartitionExtensionClause, TPartitioningLevel, TPartitionSplitMergeClause, TPathSqlNode, TPerformSqlNode, TPeriodForClause, TPhysicalAttributesClause, TPhysicalAttributesItem, TPhysicalProperties, TPivotedTable, TPivotInClause, TPrecisionScale, TPredictArgument, TPrepareSqlNode, TProcedureOption, TPTNodeList, TPxGranule, TQualifyClause, TQueryHint, TRangeNFunctionItem, TRangeSubpartitionDesc, TRangeValuesClause, TReclaimChoice, TRedshiftTableAttributes, TRelationExpr, TReplaceExprAsIdentifier, TResetSqlNode, TRestrictionClause, TResultCacheClause, TResultSetDefinition, TReturningClause, TReturnSqlNode, TRevokeSqlNode, TRoleOption, TRoleSpec, TRollbackSqlNode, TRollupCube, TSampleClause, TScriptSqlNode, TSegmentAttributesClause, TSegmentAttributesItem, TSelectDistinct, TSelectModifier, TSelectSqlNode, TSemanticAttributeDef, TSemanticRelationshipDef, TSemanticTableDef, TSemanticViewClause, TSequenceOption, TSetAssignment, TSetRowCountSqlNode, TSetSessionSqlNode, TSetSqlNode, TSignalSqlNode, TSizeClause, TSortBy, TStageLocation, TStageReference, TStatementList, TStatementSqlNode, TStorageClause, TStorageItem, TStreamingClause, TStubStmtSqlNode, TSubPartitionByClause, TSubscripts, TSupplementalLogging, TSybaseDumpTranSqlNode, TSybaseUpdateIndexStatisticsSqlNode, TTableElement, TTableHint, TTablePartitionItem, TTableProperties, TTableReference, TTableSample, TTableSamplePart, TTaskOption, TTDUnpivot, TTeradataGiveSqlNode, TTeradataLockClause, TTeradataLockSqlNode, TTeradataStmtStubSqlNode, TTeradataUsingSqlNode, TTeradataWithClause, TTeradataWithClauseItem, TTimeSeries, TTimeTravel, TTimingPoint, TTopClause, TTriggerAction, TTriggerEventClause, TTriggerEventItem, TTriggeringClause, TTriggerReferencingClause, TTriggerReferencingItem, TTrimArgument, TTruncateTableSqlNode, TTryCatchSqlNode, TTypeAttribute, TTypeName, TUnloadSqlNode, TUnnestClause, TUnpackOption, TUnpivotInClause, TUnpivotInClauseItem, TUnsetSqlNode, TUpdateFor, TUpdateSqlNode, TUpsertSqlNode, TUseKeyIndex, TVacuumSqlNode, TValueClause, TValueRowItem, TViewAliasClause, TViewAliasItem, TWhenClauseItem, TWhereClause, TWindowClause, TWindowDef, TWindowDefinition, TWindowFrame, TWindowFrameBoundary, TWindowPartitioningSpec, TWindowSpecification, TWithinGroup, TWithTableLock, TWritetextSqlNode, TXMLAttributesClause, TXmlElement, TXMLPassingClause, TXmlRoot, TXmlSerialize, TXmlTable, TXmlTableParameter

public abstract class TParseTreeNode extends Object implements Visitable, Iterator<TSourceToken>

TParseTreeNode - Core Parse Tree Node Implementation

Overview

This class is the root class for all syntax/parse tree nodes in the GSP SQL Parser. A parse tree node represents a syntactic element of a SQL statement, composed of a sequence of tokens generated by the lexer. The node maintains references to its start and end tokens in a double-linked token chain, enabling both traversal and modification of the SQL text.

Architecture and Design

Token Chain Structure

The parse tree is built on a double-linked list of TSourceToken objects. Each node:
  • Has a startToken and endToken that define its boundaries
  • Can iterate through its tokens using the token chain links
  • Maintains relationships with other nodes that may share the same tokens

Critical: Node Nesting and Token Sharing

Nodes in the parse tree are nested and share tokens. This is fundamental to the design:
  • A WHERE clause node contains an expression node, both sharing the same tokens
  • A SELECT statement contains multiple clauses, all sharing tokens from the same chain
  • Each token maintains stacks of nodes that start/end on it (via nodesStartFromThisToken and nodesEndWithThisToken)

Token Sharing Example:

 SQL: "SELECT * FROM table WHERE id = 1"
 
 - SelectStatement node: [SELECT...1]
   - SelectList node: [*]
   - FromClause node: [FROM table]
   - WhereClause node: [WHERE id = 1]
     - Expression node: [id = 1]
       - LeftOperand: [id]
       - Operator: [=]
       - RightOperand: [1]
 

Modification Strategy for Nested Nodes

Core Rules:

  1. Leaf-First Modification: Always modify the most specific (leaf) node when possible
  2. Status Propagation: When a node is modified, all overlapping nodes are updated:
    • nsDetached: Node's tokens were partially modified
    • nsPartitial: Node contains modified sub-nodes
    • nsRemoved: Node's tokens were completely removed
  3. Chain Integrity: The token chain must remain valid after any modification

Modification Scenarios and Handling:

Scenario 1: Modifying a Leaf Node
 // Original: WHERE id = 1
 // Modify the right operand from "1" to "100"
 rightOperandNode.setString("100");
 
 Result:
 - RightOperand node: replaced with new token "100"
 - Expression node: status = nsPartitial (contains modified child)
 - WhereClause node: status = nsPartitial (contains modified descendant)
 
Scenario 2: Modifying a Parent Node
 // Original: WHERE id = 1
 // Replace entire WHERE clause
 whereClauseNode.setString("WHERE status = 'active'");
 
 Result:
 - All child nodes (Expression, operands): status = nsDetached
 - WhereClause node: completely replaced with new tokens
 - SelectStatement: updated to reference new WHERE tokens
 
Scenario 3: Removing a Node
 // Remove WHERE clause entirely
 whereClauseNode.removeTokens();
 
 Result:
 - WhereClause and all children: status = nsRemoved
 - Tokens removed from chain
 - Parent SelectStatement: adjusted boundaries
 

Best Practices for API Users

  1. Check Node Status Before Modification:
           if (node.getNodeStatus() == ENodeStatus.nsNormal) {
               // Safe to modify
               node.setString(newText);
           }
           
  2. Prefer Leaf Node Modifications:
           // GOOD: Modify specific value
           tableNameNode.setString("new_table");
           
           // AVOID: Replacing entire FROM clause when only table name needs change
           fromClause.setString("FROM new_table");
           
  3. Use toScript() for Complex Modifications:
           // After multiple modifications, use script generator
           if (statement.isChanged()) {
               String result = statement.toScript();
           }
           
  4. Understand Cascading Effects:
           // Modifying a node affects all overlapping nodes
           expression.setString("new_condition");
           // Parent WHERE clause is now marked as modified
           assert whereClause.getNodeStatus() == ENodeStatus.nsPartitial;
           

Text Modification Mechanism

The node supports dynamic text modification through the setString(String) method:
  1. Tokenization: New text is tokenized using TSingletonParser to create new tokens
  2. Chain Replacement: Old tokens are removed from the chain and replaced with new ones
  3. Relationship Updates: All nodes sharing the modified tokens are updated:
    • updateNodeWithTheSameStartToken(): Updates nodes starting at modified position
    • updateMeNodeWithTheSameEndToken(): Updates nodes ending at modified position
    • updateStatusOfNodeShareSameTokens(): Propagates status changes
  4. Status Tracking: Node status changes to track modifications

String Reconstruction (toString())

The toString() method uses a sophisticated two-pass algorithm when doubleLinkedTokenListToString is true:
  • First Pass: Detects chain modifications and marks redundant newlines for deletion
  • Second Pass: Builds the final string by concatenating non-deleted tokens
This approach cleanly handles both original parsed text and user modifications.

Current Implementation Trade-offs

Design Decisions (Simplicity over Features)

  • Re-tokenization on Every Modification: Simple but potentially expensive. Accepted trade-off for reliability and consistency.
  • No Partial Token Modification: Cannot modify part of a token; must replace entire token. Keeps token integrity and chain management simple.
  • Status-based Conflict Resolution: When nodes overlap, status flags determine behavior. Simple rule-based system rather than complex conflict resolution.
  • Single Token Chain: All nodes reference the same global chain. Simpler than managing multiple chains but requires careful synchronization.

Limitations by Design

  • Cannot Preserve Comments in Modified Nodes: When a node is replaced via setString(), internal comments are lost. This is acceptable for most use cases.
  • No Undo/Redo: Modifications are permanent. Applications must manage their own undo stack.
  • Thread Safety: Not thread-safe by design. Simpler implementation, caller must synchronize.
  • Memory vs Speed: Keeps all tokens in memory for fast access. Not optimized for very large SQLs.

Implementation Details

Token Sharing Management

When modifying a node with shared tokens:
  1. Calculate token count for all affected nodes (refreshAllNodesTokenCount())
  2. Identify nodes with same start/end tokens
  3. Update node boundaries based on token count comparison:
    • Same count = sibling node, needs same update
    • Larger count = parent node, needs boundary adjustment
    • Smaller count = child node, may become detached
  4. Splice new tokens into chain maintaining prev/next links

Status Flags and Their Meanings

  • nsNormal: Unmodified node with original tokens
  • nsFlattened: Node created from user text (no original tokens)
  • nsPartitial: Contains modified child nodes but own tokens unchanged
  • nsDetached: Tokens modified by parent/sibling operation
  • nsRemoved: Tokens removed from chain, node is defunct

Proposed Future Improvements

1. Decouple Lexer Reference

 // Instead of token->lexer reference, use a TokenContext:
 class TokenContext {
     EDbVendor vendor;
     SourceBuffer sourceBuffer;
     int sourceId; // Identifies original vs modified source
 }
 

2. Implement SourceBuffer System

 class SourceBuffer {
     List<TextSegment> segments;
     
     class TextSegment {
         String text;
         SourceType type; // ORIGINAL, USER_MODIFIED, GENERATED
         int startOffset;
         int endOffset;
     }
     
     String getText(int segmentId, int start, int end);
     int addSegment(String text, SourceType type);
 }
 

3. Token Source Tracking

 class TSourceToken {
     int sourceBufferId;
     int segmentId;
     int startOffset;
     int endOffset;
     SourceType sourceType;
     
     String getText() {
         return SourceBufferManager.getBuffer(sourceBufferId)
                                  .getText(segmentId, startOffset, endOffset);
     }
 }
 

4. Lazy Token Creation

  • Don't re-tokenize for simple text replacements
  • Create synthetic tokens only when necessary
  • Reuse existing tokens when possible

5. Unified Modification API

 class NodeModification {
     ModificationType type; // REPLACE, INSERT, DELETE
     String newText;
     boolean preserveFormatting;
     boolean retokenize;
 }
 
 public void modifyNode(NodeModification mod) {
     // Single entry point for all modifications
 }
 

Critical Methods Documentation

setString(String)

Main entry point for modifying node text. Process:
  1. Tokenizes new text using TSingletonParser
  2. Creates new token chain from tokenized text
  3. Replaces old tokens in the chain
  4. Updates all affected node relationships

toString()

Reconstructs text from token chain. Two-pass algorithm:
  1. Pass 1: Detect modifications and mark redundant formatting
  2. Pass 2: Build string from valid tokens

setText(TSourceToken, TSourceToken)

Low-level token replacement. Core of the modification system:
  • Updates token chain links
  • Maintains node relationships
  • Handles edge cases (null tokens, chain boundaries)

Usage Patterns

Reading Original Text

 TParseTreeNode node = ...;
 String originalText = node.toString(); // Get text from token chain
 

Modifying Node Text

 node.setString("new SQL text"); // Replace node's text
 String modifiedText = node.toString(); // Get modified text
 

Checking Modifications

 if (node.isChanged()) {
     String newText = node.toScript(); // Use script generator for complex mods
 }
 

Thread Safety

This class is NOT thread-safe. Concurrent modifications to the token chain or node structure may result in inconsistent state or corruption.

Performance Considerations

  • Token chain traversal is O(n) where n is number of tokens
  • Text modification requires re-tokenization (expensive)
  • toString() performs two passes over tokens
  • Node relationship updates can cascade to many nodes
Since:
1.0
See Also:
  • Field Details

  • Constructor Details

  • Method Details

    • setEvaluateDatatype

      public void setEvaluateDatatype(Class<?> evaluateDatatype)
    • getEvaluateDatatype

      Support String, Integer, Double and Boolean type
      Returns:
    • setEvalValue

      public void setEvalValue(Object evalValue)
    • getEvalValue

      public Object getEvalValue()
    • setPlainText

      public void setPlainText(String plainText)
    • getPlainText

      public String getPlainText()
    • setLocation

      public void setLocation(ESqlClause location)
    • getLocation

      SQL clause that include this objectName such as select list, from clause, set clause
      Returns:
      SQL clause that include this objectName
    • getCompactString

      representation of this node by removing all spaces, return and comments
      Returns:
      string representation of this node by removing all spaces, return and comments
    • getMd5

      public String getMd5()
      md5 hash code of the string representation of this node. If the string of this node is empty, return the md5 value of the class name of this node. 1. remove all spaces, return, comments inside the node
      2. turn number constant in where clause into ? character.
      3. turn string constant in where clause into ?? character.
      4. turn all string of the token into uppercase if it's not a delimited identifier.
      Returns:
      md5 hash code of the string representation of this node
    • getParentObjectName

    • setParent

      public void setParent(TParseTreeNode parent)
    • insertAfterAToken

      public void insertAfterAToken(TSourceToken anchorToken)
    • insertNewNodeBeforeMe

      public void insertNewNodeBeforeMe(TParseTreeNode newNode, boolean needCommaBefore)
    • appendNewNode

      public void appendNewNode(TParseTreeNode newNode, boolean needCommaBefore)
    • replaceWithNewNode

      public void replaceWithNewNode(TParseTreeNode newNode)
    • resetIterator

      public void resetIterator()
    • hasNext

      public boolean hasNext()
      Specified by:
      hasNext in interface Iterator<TSourceToken>
    • next

      public TSourceToken next()
      Specified by:
      next in interface Iterator<TSourceToken>
    • remove

      public void remove()
      Specified by:
      remove in interface Iterator<TSourceToken>
    • setNodeStatus

      public void setNodeStatus(ENodeStatus nodeStatus)
    • getNodeStatus

    • addToTokenChain

      public void addToTokenChain(TSourceToken anchorToken, boolean beforeAnchorToken)
    • getTokenCount

      public int getTokenCount()
    • refreshAllNodesTokenCount

    • calculateTokenCount

      public void calculateTokenCount()
    • removeTokensBetweenToken

      public static void removeTokensBetweenToken(TSourceToken startToken, TSourceToken endToken)
      both begin and end token will be removed from the chain
      Parameters:
      startToken -
      endToken -
    • removeTokensBetweenNodes

      public static void removeTokensBetweenNodes(TParseTreeNode startNode, TParseTreeNode endNode)
    • removeTokens

      public void removeTokens()
    • getGsqlparser

      The parser that generate this node.
      Returns:
      parser that generate this node
    • setIncludingComment

      public void setIncludingComment(boolean includingComment)
    • setGsqlparser

      public void setGsqlparser(TGSqlParser gsqlparser)
    • setDummyTag

      public void setDummyTag(int dummyTag)
    • getDummyTag

      public int getDummyTag()
      A temporary value can be used for any purposes
      Returns:
      a temporary value used for any purposes
    • getStartToken

      The first token in this parse tree node
      Returns:
      the first token of node
    • getEndToken

      The last token of the node
      Returns:
      the last token of node
    • getColumnNo

      public long getColumnNo()
      Column position of the first token of this node
      Returns:
      column position
    • getLineNo

      public long getLineNo()
      Line number of the first token of this node
      Returns:
      line number
    • setNodeType

      public void setNodeType(int nodeType)
      Set the node type for this node.
      Parameters:
      nodeType - The node type.
    • getNodeType

      public int getNodeType()
      A unique value to distinguish this node from others
      Returns:
      enum value of node type
      See Also:
    • init

      public void init(Object arg1)
      Initialize a query tree node. Used internally
      Parameters:
      arg1 - first argument
    • init

      public void init(Object arg1, Object arg2)
    • init

      public void init(Object arg1, Object arg2, Object arg3)
    • init

      public void init(Object arg1, Object arg2, Object arg3, Object arg4)
    • init

      public void init(Object arg1, Object arg2, Object arg3, Object arg4, Object arg5)
    • init

      public void init(Object arg1, Object arg2, Object arg3, Object arg4, Object arg5, Object arg6)
    • doParse

      public void doParse(TCustomSqlStatement psql, ESqlClause plocation)
      Analyze the sub-nodes inside this node. Such as build the relationship between table and column.
      Parameters:
      psql - SQL statement this node belongs to
      plocation - SQL clause this node belongs to
    • setStartToken

      public void setStartToken(ArrayList startNode)
    • setEndToken

      public void setEndToken(ArrayList endNode)
    • setStartToken

      public void setStartToken(TSourceToken newStartToken)
    • setStartToken

      public void setStartToken(TSourceTokenList startTokenList)
    • setStartToken

      public void setStartToken(TParseTreeNode startNode)
    • setStartTokenDirectly

      public void setStartTokenDirectly(TSourceToken newStartToken)
    • setEndTokenDirectly

      public void setEndTokenDirectly(TSourceToken newEndToken)
    • setEndToken

      public void setEndToken(TSourceToken newEndToken)
    • setEndToken

      public void setEndToken(TSourceTokenList endTokenList)
    • setEndToken

      public void setEndToken(TFromTableList endNode)
    • setEndToken

      public void setEndToken(TParseTreeNode endNode)
    • setString2

      public void setString2(String sqlSegment)
      Deprecated.
      since v1.8.8.0, use scriptWriter technology to modify the node Set the new string text of a node will destroy all the sub-node structure
      Parameters:
      sqlSegment - that override original text of this node.
    • setString

      public void setString(String sqlSegment)
      Set the text of the node and update the corresponding source tokens synchronously. This way, when the toString() method of the node itself or its parent node is called, it will return the modified text.
      Parameters:
      sqlSegment -
    • fastSetString

      public void fastSetString(String sqlSegment)
    • getCommentBeforeNode

      return null if no comment is found before this node.
      Returns:
      the comment before this node
    • getCommentAfterNode

    • toString2

      public String toString2()
      String representation of this parse tree node.

      This string was generated by collecting text from the start token of this node to the end token of this node. If this node was modified, then use toScript() to get string representation of this node.

      Returns:
      string representation of this parse tree node
    • toString

      public String toString()

      将一个语法树节点(TParseTreeNode)转换回它对应的原始SQL字符串。 它通过遍历一个由 startToken(起始词法单元)和 endToken(结束词法单元)界定的双向链表来实现这一功能。

      这个方法的设计采用了“两遍扫描”(Two-Pass)的策略,也就是使用了两个 while 循环。 第一个循环是预处理阶段,用于清理格式;第二个循环则负责构建最终的字符串。

      第一个 while 循环

      这个循环的主要目标是识别并“软删除”多余的换行符(newline tokens)。这种情况尤其在SQL被程序动态修改后容易出现。 这个循环本身不构建字符串,只负责分析和更新词法单元的状态。 其工作原理是:

      1. 遍历: 它从 startToken 开始,通过 getNextTokenInChain() 方法遍历到 endToken
      2. 检测链表变化: 它通过比较当前和前一个词法单元的 posinlist(词法单元在原始完整列表中的位置索引)来判断链表是否“自然”。 如果不连续,意味着词法单元被插入或重排了,此时 isChainModified 标志位会被设为 true
      3. 标记换行符: 当遇到第一个换行符时,它会设置一个标志。如果紧接着又遇到了另一个换行符,并且此时链表已经被修改过, 那么它会将这个多余的换行符标记为待删除状态。这个逻辑能有效地将代码被修改后可能产生的多个连续换行压缩成一个。
      简而言之,第一个循环是一个格式清理过程,它为后续生成整洁的字符串做准备。

      第二个 while 循环

      这个循环负责从(经过第一步清理后的)词法单元流中实际地构建最终的输出字符串。 其工作原理是:

      1. 遍历: 它再次遍历完全相同的词法单元序列。
      2. 构建字符串: 在将每个词法单元追加到 StringBuffer 之前,它会进行检查。
      3. 跳过特定单元: 如果一个词法单元在第一个循环中被标记为待删除,或者它是一个注释(且配置为不包含注释),那么它将被跳过。
      4. 拼接字符串: 对于所有未被跳过的词法单元,它会将其字符串值追加到 StringBuffer 中。
      当这个循环结束后,StringBuffer 就包含了该语法树节点的最终、重构后的SQL文本。

      Overrides:
      toString in class Object
      Returns:
      节点对应的SQL字符串。
    • isTokensInChain

      public boolean isTokensInChain()
    • addAllMyTokensToTokenList

      public int addAllMyTokensToTokenList(TSourceTokenList targetList, int index)
      Deprecated.
      since v1.8.8.0, use scriptWriter technology to modify the node Inserts tokens(from start token to end token ) of this parse tree node at the specified position in this list. Shifts the element currently at that position (if any) and any subsequent elements to the right .
      Parameters:
      targetList - the new list of source tokens
      index - the position insert the targetList
      Returns:
      length of the source token list after insert targetList
    • removeAllMyTokensFromTokenList

      protected int removeAllMyTokensFromTokenList(TSourceToken additionalToken)
      Deprecated.
      since v1.8.8.0, use scriptWriter technology to modify the node
      Parameters:
      additionalToken - usually was comma before or after this parse tree node that also need to be deleted
      Returns:
      length of the source token list after remove tokens
    • accept

      public void accept(TParseTreeVisitor v)
      Deprecated.
      Accept a visitor
      Specified by:
      accept in interface Visitable
      Parameters:
      v - visitor is a descendant class of TParseTreeVisitor
    • acceptChildren

      Accept a visitor to iterate this class and sub-nodes of this class
      Specified by:
      acceptChildren in interface Visitable
      Parameters:
      v - visitor is a descendant class of TParseTreeVisitor
    • toScript

      public String toScript()
      Return the text string of this node, the return value is the same as toString() if this node is not modified manually after created by parser.
      If this node is modified, then use this method to get string representation instead of the toString() method.
      Returns:
      text string of this node
    • setChanged

      public void setChanged()
    • isChanged

      public boolean isChanged()
      Detect wether this node is modified by checking all tokens included in this node.
      Returns:
      true if this node is modified.
    • doAppendNewNode

      protected void doAppendNewNode(TParseTreeNode newNode, TParseTreeNode anchorNode, boolean needCommaBefore)
    • setAnchorNode

      public void setAnchorNode(TParseTreeNode anchorNode)
    • getAnchorNode

    • setNewSubNode

      public void setNewSubNode(TParseTreeNode oldSubNode, TParseTreeNode newSubNode, TParseTreeNode anchorNode)
    • subNodeInNode

      public static boolean subNodeInNode(TParseTreeNode subNode, TParseTreeNode wholeNode)