Class TIndices

Object
gudusoft.gsqlparser.nodes.TParseTreeNode
gudusoft.gsqlparser.nodes.TIndices
All Implemented Interfaces:
Visitable, Iterator<TSourceToken>

public class TIndices extends TParseTreeNode
Represents indirection elements in SQL expressions, supporting both array access and qualified name syntax. This class handles two distinct syntactic patterns found in PostgreSQL and other SQL dialects.

Array Access Syntax (ARRAY_ACCESS)

Used for accessing array elements and slicing operations:
  • array_column[5] - Single element access
  • array_column[2:4] - Array slice from index 2 to 4
  • array_column[:3] - Array slice from start to index 3
  • array_column[2:] - Array slice from index 2 to end
  • array_column[:] - Full array slice

Qualified Name Syntax (QUALIFIED_NAME)

Used for accessing object fields and properties:
  • json_column.field_name - Access specific field
  • record_column.* - Access all fields
  • composite_type.attribute - Access composite type attribute

Usage Examples


 // Example SQL: SELECT users[1].name FROM user_array;
 // This creates two TIndices:
 // 1. TIndices for [1] with type ARRAY_ACCESS
 // 2. TIndices for .name with type QUALIFIED_NAME
 
 TIndices arrayAccess = ...; // represents [1]
 if (arrayAccess.isArrayAccess()) {
     TExpression index = arrayAccess.getLowerSubscript(); // gets "1"
     // Process array index...
 }
 
 TIndices fieldAccess = ...; // represents .name  
 if (fieldAccess.isQualifiedName()) {
     TObjectName fieldName = fieldAccess.getAttributeName(); // gets "name"
     // Process field access...
 }
 

SQL Examples by Database

DatabaseArray AccessField Access
PostgreSQLarr[1], arr[1:3]json_col.field, record.*
Databricksarray_col[0]struct_col.attr, json.key
Snowflakearray_col[0]variant_col.field, object.*

Type Safety and Backward Compatibility

This class maintains backward compatibility with existing code while providing type-safe access:

Complete Usage Example


 // Processing SQL: SELECT data[1:3].users.name FROM complex_table;
 // This would create a chain of TIndices in TIndirection
 
 public void processIndirection(TIndirection indirection) {
     for (TIndices indices : indirection.getIndices()) {
         switch (indices.getIndicesType()) {
             case ARRAY_ACCESS:
                 System.out.println("Array access detected:");
                 TExpression lower = indices.getLowerSubscript();
                 TExpression upper = indices.getUpperSubscript();
                 
                 if (lower != null && upper != null) {
                     System.out.println("  Slice: [" + lower + ":" + upper + "]");
                 } else if (lower != null) {
                     System.out.println("  Single element: [" + lower + "]");
                 }
                 break;
                 
             case QUALIFIED_NAME:
                 System.out.println("Field access detected:");
                 TObjectName field = indices.getAttributeName();
                 System.out.println("  Field: ." + field.toString());
                 break;
         }
     }
 }
 
 // Legacy compatibility - existing code still works
 if (indices.isRealIndices()) {
     // Handle as array access (legacy approach)
 } else {
     // Handle as field access (legacy approach)  
 }
 
Since:
PostgreSQL parser support
See Also:
  • Constructor Details

  • Method Details

    • getAttributeName

      Gets the attribute name for qualified name access patterns. This is only populated for QUALIFIED_NAME type indices (e.g., .field, .*).

      Examples:

      • For json_col.user_name → returns "user_name"
      • For record.* → returns "*"
      • For array[5] → returns null (not a qualified name)
      Returns:
      the attribute/field name for qualified access, or null for array access
      See Also:
    • getLowerSubscript

      Gets the lower bound expression for array access patterns. This represents the starting index or single index in array access operations.

      Examples:

      • For arr[5] → returns expression "5"
      • For arr[2:8] → returns expression "2"
      • For arr[:3] → returns null (no lower bound)
      • For obj.field → returns null (not array access)
      Returns:
      the lower bound expression, or null if not applicable
      See Also:
    • getUpperSubscript

      Gets the upper bound expression for array slice patterns. This represents the ending index in array slice operations (e.g., [start:end]).

      Examples:

      • For arr[2:8] → returns expression "8"
      • For arr[:3] → returns expression "3"
      • For arr[5] → returns null (single element, not slice)
      • For arr[2:] → returns null (no upper bound)
      Returns:
      the upper bound expression for slices, or null if not a slice or no upper bound
      See Also:
    • isRealIndices

      public boolean isRealIndices()
      Deprecated.
      Use isArrayAccess() for better code clarity
      Legacy method to check if this represents "real" array indices.

      Note: This method is maintained for backward compatibility. For new code, prefer using isArrayAccess() and isQualifiedName() for clearer semantic meaning.

      Returns true for array access patterns and false for qualified name patterns:

      • arr[5] → true (real array indices)
      • arr[2:4] → true (real array slice)
      • obj.field → false (not real indices, just field access)
      Returns:
      true if this represents array access, false for qualified name access
    • getIndicesType

      Gets the explicit type of this indices element.

      This method returns the semantic type of the indirection, helping distinguish between array access operations and qualified name field access. The method includes fallback logic for backward compatibility with legacy code.

      Type determination logic:

      1. If explicit type was set via setIndicesType(IndicesType), return that
      2. Otherwise, infer from legacy fields: attributeName present → QUALIFIED_NAME, absent → ARRAY_ACCESS
      Returns:
      TIndices.IndicesType.ARRAY_ACCESS for bracket notation or TIndices.IndicesType.QUALIFIED_NAME for dot notation
      See Also:
    • setIndicesType

      public void setIndicesType(TIndices.IndicesType indicesType)
      Sets the explicit type of this indices element.

      This method is typically called by the parser to explicitly mark whether an indices element represents array access or qualified name access.

      Parameters:
      indicesType - the semantic type to set - TIndices.IndicesType.ARRAY_ACCESS for bracket notation or TIndices.IndicesType.QUALIFIED_NAME for dot notation
      See Also:
    • isSlice

      public boolean isSlice()
      Checks if this represents an array slice operation (contains colon syntax).

      Returns true for slice patterns that contain a colon:

      • arr[2:8] - Slice with both bounds
      • arr[:3] - Slice with upper bound only
      • arr[2:] - Slice with lower bound only
      • arr[:] - Full slice

      Returns false for single element access:

      • arr[5] - Single element access (no colon)
      Returns:
      true if this represents a slice operation with colon syntax
      See Also:
    • setSlice

      public void setSlice(boolean isSlice)
      Sets whether this represents an array slice operation.

      This method is typically called by the parser to indicate whether the original syntax contained a colon (slice) or not (single element).

      Parameters:
      isSlice - true if this represents slice syntax with colon, false for single element
      See Also:
    • isArrayAccess

      public boolean isArrayAccess()
      Checks if this represents array access syntax using bracket notation.

      Returns true for all forms of array/list access patterns:

      • arr[5] - Single element access
      • arr[2:8] - Array slice with both bounds
      • arr[:3] - Array slice to index 3
      • arr[2:] - Array slice from index 2
      • arr[:] - Full array slice

      This is the preferred method for type-safe checking of array access patterns.

      Returns:
      true if this represents array access using bracket notation
      See Also:
    • isQualifiedName

      public boolean isQualifiedName()
      Checks if this represents qualified name syntax using dot notation.

      Returns true for all forms of field/property access patterns:

      • obj.field_name - Access specific field
      • json_col.key - Access JSON object key
      • record.* - Access all fields (wildcard)
      • composite_type.attribute - Access composite type attribute

      This is the preferred method for type-safe checking of qualified name patterns.

      Returns:
      true if this represents qualified name access using dot notation
      See Also:
    • init

      public void init(Object arg1, Object arg2, Object arg3)
      Initializes this TIndices with the specified components.

      This method is typically called by the parser during AST construction. The parameters determine the type and content of the indices element:

      For Array Access: arg1=null, arg2=lowerBound, arg3=upperBound

      For Qualified Names: arg1=attributeName, arg2=null, arg3=null

      Overrides:
      init in class TParseTreeNode
      Parameters:
      arg1 - attribute name for qualified access, or null for array access
      arg2 - lower bound expression for array access, or null for qualified names
      arg3 - upper bound expression for array slices, or null for single elements or qualified names
    • setLowerSubscript

      public void setLowerSubscript(TExpression lowerSubscript)
      Sets the lower bound expression for array access operations.

      This represents the starting index in array access patterns:

      • For [5] → set to expression "5"
      • For [2:8] → set to expression "2"
      • For [:3] → set to null (no lower bound)
      Parameters:
      lowerSubscript - the expression representing the lower bound, or null
      See Also:
    • setUpperSubscript

      public void setUpperSubscript(TExpression upperSubscript)
      Sets the upper bound expression for array slice operations.

      This represents the ending index in array slice patterns:

      • For [2:8] → set to expression "8"
      • For [:3] → set to expression "3"
      • For [5] → set to null (single element, not a slice)
      Parameters:
      upperSubscript - the expression representing the upper bound, or null
      See Also:
    • setAttributeName

      public void setAttributeName(TObjectName attributeName)
      Sets the attribute name for qualified name access operations.

      This represents the field or property name in dot notation patterns:

      • For .field_name → set to "field_name"
      • For .* → set to "*"
      • For array access → should be null
      Parameters:
      attributeName - the object name representing the field/property, or null for array access
      See Also:
    • getSubscriptList

    • addSubscript

      public void addSubscript(TExpression expr)
    • addSubscript

      public static void addSubscript(ArrayList<TIndices> indicesArrayList, TExpression expr)
    • accept

      public void accept(TParseTreeVisitor v)
      Description copied from class: TParseTreeNode
      Accept a visitor
      Specified by:
      accept in interface Visitable
      Overrides:
      accept in class TParseTreeNode
      Parameters:
      v - visitor is a descendant class of TParseTreeVisitor
    • acceptChildren

      Description copied from class: TParseTreeNode
      Accept a visitor to iterate this class and sub-nodes of this class
      Specified by:
      acceptChildren in interface Visitable
      Overrides:
      acceptChildren in class TParseTreeNode
      Parameters:
      v - visitor is a descendant class of TParseTreeVisitor