public class TIndices extends TParseTreeNode
array_column[5] - Single element accessarray_column[2:4] - Array slice from index 2 to 4array_column[:3] - Array slice from start to index 3array_column[2:] - Array slice from index 2 to endarray_column[:] - Full array slicejson_column.field_name - Access specific fieldrecord_column.* - Access all fieldscomposite_type.attribute - Access composite type attribute
// 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...
}
| Database | Array Access | Field Access |
|---|---|---|
| PostgreSQL | arr[1], arr[1:3] | json_col.field, record.* |
| Databricks | array_col[0] | struct_col.attr, json.key |
| Snowflake | array_col[0] | variant_col.field, object.* |
isRealIndices() - Legacy method, still works as beforeisArrayAccess() - New type-safe method for array accessisQualifiedName() - New type-safe method for field accessgetIndicesType() - Get explicit type information
// 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)
}
TIndirection,
TExpression,
TObjectName| Modifier and Type | Class and Description |
|---|---|
static class |
TIndices.IndicesType
Enum to distinguish between array access syntax and qualified name syntax.
|
dbvendor, doubleLinkedTokenListToString, nodeActionAppend, nodeActionInsert, nodeActionRemove, nodeActionUnknown, nodeActionUpdate, nodeActionUpdateText, nodeChangeEndToken, nodeChangeStartToken| Constructor and Description |
|---|
TIndices() |
| Modifier and Type | Method and Description |
|---|---|
void |
accept(TParseTreeVisitor v)
Accept a visitor
|
void |
acceptChildren(TParseTreeVisitor v)
Accept a visitor to iterate this class and sub-nodes of this class
|
static void |
addSubscript(ArrayList<TIndices> indicesArrayList,
TExpression expr) |
void |
addSubscript(TExpression expr) |
TObjectName |
getAttributeName()
Gets the attribute name for qualified name access patterns.
|
TIndices.IndicesType |
getIndicesType()
Gets the explicit type of this indices element.
|
TExpression |
getLowerSubscript()
Gets the lower bound expression for array access patterns.
|
TExpressionList |
getSubscriptList() |
TExpression |
getUpperSubscript()
Gets the upper bound expression for array slice patterns.
|
void |
init(Object arg1,
Object arg2,
Object arg3)
Initializes this TIndices with the specified components.
|
boolean |
isArrayAccess()
Checks if this represents array access syntax using bracket notation.
|
boolean |
isQualifiedName()
Checks if this represents qualified name syntax using dot notation.
|
boolean |
isRealIndices()
Deprecated.
Use
isArrayAccess() for better code clarity |
boolean |
isSlice()
Checks if this represents an array slice operation (contains colon syntax).
|
void |
setAttributeName(TObjectName attributeName)
Sets the attribute name for qualified name access operations.
|
void |
setIndicesType(TIndices.IndicesType indicesType)
Sets the explicit type of this indices element.
|
void |
setLowerSubscript(TExpression lowerSubscript)
Sets the lower bound expression for array access operations.
|
void |
setSlice(boolean isSlice)
Sets whether this represents an array slice operation.
|
void |
setUpperSubscript(TExpression upperSubscript)
Sets the upper bound expression for array slice operations.
|
addAllMyTokensToTokenList, addToTokenChain, appendNewNode, calculateTokenCount, doAppendNewNode, doParse, fastSetString, getAnchorNode, getColumnNo, getCommentAfterNode, getCommentBeforeNode, getCompactString, getDummyTag, getEndToken, getEvaluateDatatype, getEvalValue, getGsqlparser, getLineNo, getLocation, getMd5, getNodeStatus, getNodeType, getParentObjectName, getPlainText, getStartToken, getTokenCount, hasNext, init, init, init, init, init, init, init, init, init, insertAfterAToken, insertNewNodeBeforeMe, isChanged, isTokensInChain, next, refreshAllNodesTokenCount, remove, removeAllMyTokensFromTokenList, removeTokens, removeTokensBetweenNodes, removeTokensBetweenToken, replaceWithNewNode, resetIterator, setAnchorNode, setChanged, setDummyTag, setEndToken, setEndToken, setEndToken, setEndToken, setEndToken, setEndTokenDirectly, setEvaluateDatatype, setEvalValue, setGsqlparser, setIncludingComment, setLocation, setNewSubNode, setNodeStatus, setNodeType, setParent, setPlainText, setStartToken, setStartToken, setStartToken, setStartToken, setStartTokenDirectly, setString, setString2, subNodeInNode, toScript, toString, toString2clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, waitforEachRemainingpublic TIndices()
public TObjectName getAttributeName()
Examples:
json_col.user_name → returns "user_name"record.* → returns "*"array[5] → returns null (not a qualified name)isQualifiedName()public TExpression getLowerSubscript()
Examples:
arr[5] → returns expression "5"arr[2:8] → returns expression "2"arr[:3] → returns null (no lower bound)obj.field → returns null (not array access)getUpperSubscript(),
isArrayAccess()public TExpression getUpperSubscript()
Examples:
arr[2:8] → returns expression "8"arr[:3] → returns expression "3"arr[5] → returns null (single element, not slice)arr[2:] → returns null (no upper bound)getLowerSubscript(),
isArrayAccess()public boolean isRealIndices()
isArrayAccess() for better code clarityNote: 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)public TIndices.IndicesType getIndicesType()
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:
setIndicesType(IndicesType), return thatTIndices.IndicesType.ARRAY_ACCESS for bracket notation or TIndices.IndicesType.QUALIFIED_NAME for dot notationisArrayAccess(),
isQualifiedName()public void setIndicesType(TIndices.IndicesType indicesType)
This method is typically called by the parser to explicitly mark whether an indices element represents array access or qualified name access.
indicesType - the semantic type to set - TIndices.IndicesType.ARRAY_ACCESS
for bracket notation or TIndices.IndicesType.QUALIFIED_NAME for dot notationgetIndicesType()public boolean isSlice()
Returns true for slice patterns that contain a colon:
arr[2:8] - Slice with both boundsarr[:3] - Slice with upper bound onlyarr[2:] - Slice with lower bound onlyarr[:] - Full sliceReturns false for single element access:
arr[5] - Single element access (no colon)setSlice(boolean)public void setSlice(boolean isSlice)
This method is typically called by the parser to indicate whether the original syntax contained a colon (slice) or not (single element).
isSlice - true if this represents slice syntax with colon, false for single elementisSlice()public boolean isArrayAccess()
Returns true for all forms of array/list access patterns:
arr[5] - Single element accessarr[2:8] - Array slice with both boundsarr[:3] - Array slice to index 3arr[2:] - Array slice from index 2arr[:] - Full array sliceThis is the preferred method for type-safe checking of array access patterns.
isQualifiedName(),
getLowerSubscript(),
getUpperSubscript()public boolean isQualifiedName()
Returns true for all forms of field/property access patterns:
obj.field_name - Access specific fieldjson_col.key - Access JSON object keyrecord.* - Access all fields (wildcard)composite_type.attribute - Access composite type attributeThis is the preferred method for type-safe checking of qualified name patterns.
isArrayAccess(),
getAttributeName()public void init(Object arg1, Object arg2, Object arg3)
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
init in class TParseTreeNodearg1 - attribute name for qualified access, or null for array accessarg2 - lower bound expression for array access, or null for qualified namesarg3 - upper bound expression for array slices, or null for single elements or qualified namespublic void setLowerSubscript(TExpression lowerSubscript)
This represents the starting index in array access patterns:
[5] → set to expression "5"[2:8] → set to expression "2"[:3] → set to null (no lower bound)lowerSubscript - the expression representing the lower bound, or nullgetLowerSubscript()public void setUpperSubscript(TExpression upperSubscript)
This represents the ending index in array slice patterns:
[2:8] → set to expression "8"[:3] → set to expression "3"[5] → set to null (single element, not a slice)upperSubscript - the expression representing the upper bound, or nullgetUpperSubscript()public void setAttributeName(TObjectName attributeName)
This represents the field or property name in dot notation patterns:
.field_name → set to "field_name".* → set to "*"attributeName - the object name representing the field/property, or null for array accessgetAttributeName()public TExpressionList getSubscriptList()
public void addSubscript(TExpression expr)
public static void addSubscript(ArrayList<TIndices> indicesArrayList, TExpression expr)
public void accept(TParseTreeVisitor v)
TParseTreeNodeaccept in interface Visitableaccept in class TParseTreeNodev - visitor is a descendant class of TParseTreeVisitorpublic void acceptChildren(TParseTreeVisitor v)
TParseTreeNodeacceptChildren in interface VisitableacceptChildren in class TParseTreeNodev - visitor is a descendant class of TParseTreeVisitor