001 002package gudusoft.gsqlparser.dlineage.dataflow.model; 003 004import java.util.LinkedHashSet; 005import java.util.Set; 006 007import gudusoft.gsqlparser.EDbVendor; 008import gudusoft.gsqlparser.EExpressionType; 009import gudusoft.gsqlparser.ESetOperatorType; 010import gudusoft.gsqlparser.TSourceToken; 011import gudusoft.gsqlparser.dlineage.util.DlineageUtil; 012import gudusoft.gsqlparser.dlineage.util.Pair3; 013import gudusoft.gsqlparser.nodes.TObjectName; 014import gudusoft.gsqlparser.nodes.TResultColumn; 015import gudusoft.gsqlparser.sqlenv.TSQLEnv; 016import gudusoft.gsqlparser.stmt.TSelectSqlStatement; 017import gudusoft.gsqlparser.util.SQLUtil; 018 019public class SelectSetResultColumn extends ResultColumn { 020 021 private LinkedHashSet<String> aliasSet = new LinkedHashSet<String>(); 022 023 public SelectSetResultColumn(ResultSet resultSet, 024 TResultColumn resultColumnObject, int index) { 025 super(resultSet, resultColumnObject); 026 aliasSet.clear(); 027 if (isNotSameAlias(resultSet, index)) { 028 this.name = aliasSet.iterator().next(); 029 } else { 030 if (resultColumnObject.getAliasClause() != null) { 031 this.name = resultColumnObject.getAliasClause().toString(); 032 } else if (resultColumnObject.getColumnNameOnly() != null 033 && !"".equals(resultColumnObject.getColumnNameOnly())) { 034 this.name = resultColumnObject.getColumnNameOnly(); 035 } else if (resultColumnObject.getExpr().getExpressionType() == EExpressionType.simple_constant_t) { 036 this.name = resultColumnObject.getExpr().toString(); 037 } 038 else { 039 this.name = quote(resultColumnObject.toString()); 040 } 041 } 042 043 this.fullName = this.name; 044 } 045 046 private boolean isNotSameAlias(ResultSet resultSet, int index) { 047 if (resultSet instanceof SelectSetResultSet) { 048 SelectSetResultSet selectSetResultSet = (SelectSetResultSet) resultSet; 049 if (selectSetResultSet 050 .getSetOperatorType() == ESetOperatorType.none) { 051 return false; 052 } 053 TSelectSqlStatement select = selectSetResultSet.getSelectObject(); 054 return isNotSameAlias(select, index); 055 } else if (resultSet instanceof SelectResultSet) { 056 SelectResultSet selectResultSet = (SelectResultSet) resultSet; 057 if (selectResultSet.getSelectStmt() 058 .getSetOperatorType() == ESetOperatorType.none) { 059 return false; 060 } 061 TSelectSqlStatement select = selectResultSet.getSelectStmt(); 062 return isNotSameAlias(select, index); 063 } 064 return false; 065 } 066 067 private boolean isNotSameAlias(TSelectSqlStatement select, int index) { 068 collectSelectAlias(select, index, aliasSet); 069 aliasSet.remove("*"); 070 return aliasSet.size() > 1; 071 } 072 073 private void collectSelectAlias(TSelectSqlStatement select, int index, 074 Set<String> aliasSet) { 075 // Iterative traversal using explicit stack to avoid StackOverflow 076 java.util.Deque<TSelectSqlStatement> stack = new java.util.ArrayDeque<>(); 077 stack.push(select); 078 079 while (!stack.isEmpty()) { 080 TSelectSqlStatement current = stack.pop(); 081 if (current.getSetOperatorType() == ESetOperatorType.none) { 082 if (current.getResultColumnList() == null) { 083 continue; 084 } 085 TResultColumn column = current.getResultColumnList() 086 .getResultColumn(index); 087 088 String alias = null; 089 if (column == null) { 090 continue; 091 } 092 if (column.getAliasClause() != null) { 093 alias = column.getAliasClause().toString(); 094 } else if (column.getColumnNameOnly() != null && !"".equals(column.getColumnNameOnly())) { 095 alias = column.getColumnNameOnly(); 096 } else if (column.getExpr().getExpressionType() == EExpressionType.simple_constant_t) { 097 alias = column.getExpr().toString(); 098 } else { 099 alias = quote(column.toString()); 100 } 101 aliasSet.add(alias); 102 } else { 103 // Push right first so left is processed first 104 if (current.getRightStmt() != null) stack.push(current.getRightStmt()); 105 if (current.getLeftStmt() != null) stack.push(current.getLeftStmt()); 106 } 107 } 108 } 109 110 private String quote(String column) { 111 EDbVendor vendor = ModelBindingManager.getGlobalVendor(); 112 String delimitedChar = TSQLEnv.delimitedChar(vendor); 113 if (!DlineageUtil.isQuote(column)){ 114 if(vendor == EDbVendor.dbvmssql || vendor == EDbVendor.dbvazuresql) { 115 return "[" + column + "]"; 116 } 117 else { 118 return delimitedChar + column + delimitedChar; 119 } 120 } 121 else return column; 122 } 123 124 public SelectSetResultColumn(ResultSet resultSet, 125 ResultColumn resultColumn) { 126 if (resultColumn == null || resultSet == null) 127 throw new IllegalArgumentException( 128 "ResultColumn arguments can't be null."); 129 130 id = ++ModelBindingManager.get().TABLE_COLUMN_ID; 131 132 this.resultSet = resultSet; 133 resultSet.addColumn(this); 134 this.setStruct(resultColumn.isStruct()); 135 136 if(resultColumn.getRefColumnName()!=null) { 137 TResultColumn resultColumnObject = (TResultColumn) resultColumn 138 .getColumnObject(); 139 TSourceToken startToken = resultColumnObject.getStartToken(); 140 TSourceToken endToken = resultColumnObject.getEndToken(); 141 this.startPosition = new Pair3<Long, Long, String>(startToken.lineNo, 142 startToken.columnNo, ModelBindingManager.getGlobalHash()); 143 this.endPosition = new Pair3<Long, Long, String>(endToken.lineNo, 144 endToken.columnNo + SQLUtil.endTrim(endToken.getAstext()).length(), ModelBindingManager.getGlobalHash()); 145 this.columnObject = resultColumnObject; 146 this.refColumnName = resultColumn.getRefColumnName(); 147 this.name = resultColumn.getName(); 148 } 149 else if (resultColumn.getColumnObject() instanceof TResultColumn) { 150 TResultColumn resultColumnObject = (TResultColumn) resultColumn 151 .getColumnObject(); 152 if (resultColumnObject.getAliasClause() != null) { 153 this.alias = resultColumnObject.getAliasClause().toString(); 154 TSourceToken startToken = resultColumnObject.getAliasClause() 155 .getStartToken(); 156 TSourceToken endToken = resultColumnObject.getAliasClause() 157 .getEndToken(); 158 this.aliasStartPosition = new Pair3<Long, Long, String>( 159 startToken.lineNo, startToken.columnNo, ModelBindingManager.getGlobalHash()); 160 this.aliasEndPosition = new Pair3<Long, Long, String>(endToken.lineNo, 161 endToken.columnNo + SQLUtil.endTrim(endToken.getAstext()).length(), ModelBindingManager.getGlobalHash()); 162 163 this.name = this.alias; 164 } else if (resultColumnObject.getExpr() 165 .getExpressionType() == EExpressionType.simple_object_name_t) { 166 this.name = resultColumnObject.getColumnNameOnly(); 167 } else if (resultColumnObject.getFieldAttr() != null) { 168 this.name = resultColumnObject.getColumnNameOnly(); 169 } else { 170 if (resultColumnObject.getExpr() 171 .getExpressionType() == EExpressionType.simple_constant_t) { 172 this.name = resultColumnObject.toString(); 173 } else if (resultColumnObject.getExpr() 174 .getExpressionType() == EExpressionType.function_t) { 175 this.name = resultColumnObject.getCompactString(); 176 } else if (resultColumnObject.getColumnNameOnly() != null 177 && !"".equals( 178 resultColumnObject.getColumnNameOnly())) { 179 this.name = resultColumnObject.getColumnNameOnly(); 180 } else { 181 this.name = resultColumnObject.toString(); 182 } 183 } 184 185 if (resultColumnObject.getExpr() 186 .getExpressionType() == EExpressionType.function_t) { 187 this.fullName = resultColumnObject.getExpr() 188 .getFunctionCall() 189 .getFunctionName() 190 .toString(); 191 } else { 192 this.fullName = resultColumnObject.toString(); 193 } 194 195 TSourceToken startToken = resultColumnObject.getStartToken(); 196 TSourceToken endToken = resultColumnObject.getEndToken(); 197 this.startPosition = new Pair3<Long, Long, String>(startToken.lineNo, 198 startToken.columnNo, ModelBindingManager.getGlobalHash()); 199 this.endPosition = new Pair3<Long, Long, String>(endToken.lineNo, 200 endToken.columnNo + SQLUtil.endTrim(endToken.getAstext()).length(), ModelBindingManager.getGlobalHash()); 201 this.columnObject = resultColumnObject; 202 } else if (resultColumn.getColumnObject() instanceof TObjectName) { 203 TObjectName resultColumnObject = (TObjectName) resultColumn 204 .getColumnObject(); 205 206 if (resultColumnObject.getColumnNameOnly() != null 207 && !"".equals(resultColumnObject.getColumnNameOnly())) { 208 this.name = resultColumnObject.getColumnNameOnly(); 209 } else { 210 this.name = resultColumnObject.toString(); 211 } 212 213 this.fullName = this.name; 214 215 TSourceToken startToken = resultColumnObject.getStartToken(); 216 TSourceToken endToken = resultColumnObject.getEndToken(); 217 this.startPosition = new Pair3<Long, Long, String>(startToken.lineNo, 218 startToken.columnNo, ModelBindingManager.getGlobalHash()); 219 this.endPosition = new Pair3<Long, Long, String>(endToken.lineNo, 220 endToken.columnNo + SQLUtil.endTrim(endToken.getAstext()).length(), ModelBindingManager.getGlobalHash()); 221 this.columnObject = resultColumnObject; 222 } else { 223 this.name = resultColumn.getName(); 224 this.fullName = this.name; 225 226 TSourceToken startToken = resultColumn.getColumnObject() 227 .getStartToken(); 228 TSourceToken endToken = resultColumn.getColumnObject() 229 .getEndToken(); 230 this.startPosition = new Pair3<Long, Long, String>(startToken.lineNo, 231 startToken.columnNo, ModelBindingManager.getGlobalHash()); 232 this.endPosition = new Pair3<Long, Long, String>(endToken.lineNo, 233 endToken.columnNo + SQLUtil.endTrim(endToken.getAstext()).length(), ModelBindingManager.getGlobalHash()); 234 this.columnObject = resultColumn.getColumnObject(); 235 } 236 } 237 238 public Set<String> getAliasSet() { 239 return aliasSet; 240 } 241}