001 002package gudusoft.gsqlparser.dlineage.dataflow.model; 003 004import java.util.*; 005import java.util.concurrent.atomic.AtomicInteger; 006 007import gudusoft.gsqlparser.EExpressionType; 008import gudusoft.gsqlparser.TSourceToken; 009import gudusoft.gsqlparser.dlineage.util.DlineageUtil; 010import gudusoft.gsqlparser.dlineage.util.Pair; 011import gudusoft.gsqlparser.dlineage.util.Pair3; 012import gudusoft.gsqlparser.nodes.TExpression; 013import gudusoft.gsqlparser.nodes.TObjectName; 014import gudusoft.gsqlparser.nodes.TParseTreeNode; 015import gudusoft.gsqlparser.nodes.TResultColumn; 016import gudusoft.gsqlparser.nodes.TResultColumnList; 017import gudusoft.gsqlparser.util.SQLUtil; 018 019public class ResultColumn extends Column{ 020 021 protected ResultSet resultSet; 022 023 protected long id; 024 025 protected String alias; 026 protected Pair3<Long, Long, String> aliasStartPosition; 027 protected Pair3<Long, Long, String> aliasEndPosition; 028 029 protected String fullName; 030 protected String name; 031 032 protected Pair3<Long, Long, String> startPosition; 033 protected Pair3<Long, Long, String> endPosition; 034 035 protected TParseTreeNode columnObject; 036 037 protected String refColumnName; 038 039 protected Map<String, Set<TObjectName>> starLinkColumns = new LinkedHashMap<String, Set<TObjectName>>(); 040 041 private boolean showStar = true; 042 043 protected boolean isFunction = false; 044 045 private boolean isPseduo = false; 046 047 private boolean isStruct = false; 048 049 private Transform transform; 050 051 public ResultColumn() { 052 053 } 054 055 public ResultColumn(ResultSet resultSet, TParseTreeNode columnObject) { 056 if (columnObject == null || resultSet == null) 057 throw new IllegalArgumentException("ResultColumn arguments can't be null."); 058 059 id = ++ModelBindingManager.get().TABLE_COLUMN_ID; 060 061 this.resultSet = resultSet; 062 resultSet.addColumn(this); 063 064 this.columnObject = columnObject; 065 066 TSourceToken startToken = columnObject.getStartToken(); 067 TSourceToken endToken = columnObject.getEndToken(); 068 069 if (columnObject instanceof TObjectName) { 070 if (((TObjectName) columnObject).getColumnNameOnly() != null 071 && !"".equals(((TObjectName) columnObject).getColumnNameOnly())) { 072 this.name = ((TObjectName) columnObject).getColumnNameOnly(); 073 } else { 074 this.name = ((TObjectName) columnObject).toString(); 075 } 076 this.name = SQLUtil.trimColumnStringQuote(name); 077 } else 078 this.name = columnObject.toString(); 079 080 this.fullName = columnObject.toString(); 081 082 this.startPosition = new Pair3<Long, Long, String>(startToken.lineNo, startToken.columnNo, 083 ModelBindingManager.getGlobalHash()); 084 this.endPosition = new Pair3<Long, Long, String>(endToken.lineNo, endToken.columnNo + SQLUtil.endTrim(endToken.astext).length(), 085 ModelBindingManager.getGlobalHash()); 086 } 087 088 public ResultColumn(ResultSet resultSet, TResultColumn resultColumnObject) { 089 if (resultColumnObject == null || resultSet == null) 090 throw new IllegalArgumentException("ResultColumn arguments can't be null."); 091 092 id = ++ModelBindingManager.get().TABLE_COLUMN_ID; 093 094 this.resultSet = resultSet; 095 resultSet.addColumn(this); 096 097 this.columnObject = resultColumnObject; 098 099 if (resultColumnObject.getAliasClause() != null) { 100 this.alias = resultColumnObject.getAliasClause().toString(); 101 TSourceToken startToken = resultColumnObject.getAliasClause().getStartToken(); 102 TSourceToken endToken = resultColumnObject.getAliasClause().getEndToken(); 103 this.aliasStartPosition = new Pair3<Long, Long, String>(startToken.lineNo, startToken.columnNo, 104 ModelBindingManager.getGlobalHash()); 105 this.aliasEndPosition = new Pair3<Long, Long, String>(endToken.lineNo, 106 endToken.columnNo + SQLUtil.endTrim(endToken.astext).length(), ModelBindingManager.getGlobalHash()); 107 108 if(resultSet.getAliasMap().containsKey(this.alias.toLowerCase())){ 109 int index = resultSet.getAliasMap().get(this.alias.toLowerCase()).incrementAndGet(); 110 this.name = SQLUtil.trimSingleQuote(this.alias) + "(" + index + ")"; 111 } 112 else { 113 resultSet.getAliasMap().put(this.alias.toLowerCase(), new AtomicInteger(0)); 114 this.name = SQLUtil.trimSingleQuote(this.alias); 115 } 116 } else if (resultColumnObject.getExpr() != null) { 117 this.name = getColumnName(resultColumnObject.getExpr()); 118 } 119 120 if(this.name == null){ 121 if (resultColumnObject.getColumnNameOnly() != null 122 && !"".equals(resultColumnObject.getColumnNameOnly())) { 123 if (resultColumnObject.getExpr().getObjectOperand() != null 124 && resultColumnObject.getExpr().getObjectOperand().getPropertyToken() != null) { 125 this.name = resultColumnObject.getExpr().getObjectOperand().getPropertyToken().astext; 126 } else { 127 this.name = resultColumnObject.getColumnNameOnly(); 128 } 129 } else { 130 this.name = resultColumnObject.toString(); 131 } 132 } 133 134 if (resultColumnObject.getExpr().getExpressionType() == EExpressionType.function_t) { 135 this.fullName = resultColumnObject.getExpr().getFunctionCall().toString(); 136 } else if (resultColumnObject.getExpr().getExpressionType() == EExpressionType.typecast_t) { 137 this.fullName = resultColumnObject.getExpr().getLeftOperand().toString(); 138 } else { 139 this.fullName = resultColumnObject.toString(); 140 } 141 142 TSourceToken startToken = resultColumnObject.getStartToken(); 143 TSourceToken endToken = resultColumnObject.getEndToken(); 144 this.startPosition = new Pair3<Long, Long, String>(startToken.lineNo, startToken.columnNo, 145 ModelBindingManager.getGlobalHash()); 146 this.endPosition = new Pair3<Long, Long, String>(endToken.lineNo, endToken.columnNo + SQLUtil.endTrim(endToken.astext).length(), 147 ModelBindingManager.getGlobalHash()); 148 } 149 150 public ResultColumn(ResultSet resultSet, TResultColumn resultColumnObject, String refColumnName) { 151 if (resultColumnObject == null || resultSet == null) 152 throw new IllegalArgumentException("ResultColumn arguments can't be null."); 153 154 id = ++ModelBindingManager.get().TABLE_COLUMN_ID; 155 156 this.resultSet = resultSet; 157 resultSet.addColumn(this); 158 159 this.columnObject = resultColumnObject; 160 this.refColumnName = refColumnName; 161 162 this.name = refColumnName; 163 164 TSourceToken startToken = resultColumnObject.getStartToken(); 165 TSourceToken endToken = resultColumnObject.getEndToken(); 166 this.startPosition = new Pair3<Long, Long, String>(startToken.lineNo, startToken.columnNo, 167 ModelBindingManager.getGlobalHash()); 168 this.endPosition = new Pair3<Long, Long, String>(endToken.lineNo, endToken.columnNo + SQLUtil.endTrim(endToken.astext).length(), 169 ModelBindingManager.getGlobalHash()); 170 } 171 172 protected String getColumnName(TExpression expr) { 173 if (expr.getExpressionType() == EExpressionType.simple_constant_t) { 174 return expr.toString(); 175 } else if (expr.getExpressionType() == EExpressionType.sqlserver_proprietary_column_alias_t) { 176 this.alias = expr.getLeftOperand().toString(); 177 TSourceToken startToken = expr.getLeftOperand().getStartToken(); 178 TSourceToken endToken = expr.getLeftOperand().getEndToken(); 179 this.aliasStartPosition = new Pair3<Long, Long, String>(startToken.lineNo, startToken.columnNo, 180 ModelBindingManager.getGlobalHash()); 181 this.aliasEndPosition = new Pair3<Long, Long, String>(endToken.lineNo, 182 endToken.columnNo + SQLUtil.endTrim(endToken.astext).length(), ModelBindingManager.getGlobalHash()); 183 184 return this.alias; 185 } else if (expr.getExpressionType() == EExpressionType.function_t) { 186 return expr.getFunctionCall().toString(); 187 } else if (expr.getExpressionType() == EExpressionType.typecast_t) { 188 return expr.getLeftOperand().toString(); 189 } else if (expr.getExpressionType() == EExpressionType.parenthesis_t) { 190 return getColumnName(expr.getLeftOperand()); 191 } else if (expr.getExpressionType() == EExpressionType.simple_object_name_t) { 192 TObjectName columnName = expr.getObjectOperand(); 193 if (columnName.getPropertyToken() != null) { 194 return columnName.getPropertyToken().astext; 195 } else { 196 if (SQLUtil.isEmpty(columnName.getColumnNameOnly())) { 197 return columnName.toString(); 198 } else { 199 return columnName.getColumnNameOnly(); 200 } 201 } 202 } else if (expr.getExpressionType() == EExpressionType.subquery_t) { 203 TResultColumnList resultset = expr.getSubQuery().getResultColumnList(); 204 if (resultset != null && resultset.size() == 1) { 205 TResultColumn resultColumn = resultset.getResultColumn(0); 206 if (!SQLUtil.isEmpty(resultColumn.getColumnAlias())) { 207 return resultColumn.getColumnAlias(); 208 } else if (resultColumn.getExpr() != null) { 209 return getColumnName(resultColumn.getExpr()); 210 } else if (resultColumn.getColumnNameOnly() != null 211 && !"".equals(resultColumn.getColumnNameOnly())) { 212 if (resultColumn.getExpr().getObjectOperand() != null 213 && resultColumn.getExpr().getObjectOperand().getPropertyToken() != null) { 214 this.name = resultColumn.getExpr().getObjectOperand().getPropertyToken().astext; 215 } else { 216 this.name = resultColumn.getColumnNameOnly(); 217 } 218 } else { 219 this.name = resultColumn.toString(); 220 } 221 } 222 } 223 return null; 224 } 225 226 public ResultColumn(SelectResultSet resultSet, Pair<TResultColumn, TObjectName> starColumnPair) { 227 if (starColumnPair == null || resultSet == null) 228 throw new IllegalArgumentException("ResultColumn arguments can't be null."); 229 230 id = ++ModelBindingManager.get().TABLE_COLUMN_ID; 231 232 this.resultSet = resultSet; 233 resultSet.addColumn(this); 234 235 this.columnObject = starColumnPair.first; 236 237 TSourceToken startToken = columnObject.getStartToken(); 238 TSourceToken endToken = columnObject.getEndToken(); 239 240 this.name = ((TObjectName) columnObject).getColumnNameOnly(); 241 if(name == null){ 242 name = ((TObjectName) columnObject).toString(); 243 } 244 this.fullName = columnObject.toString(); 245 246 this.startPosition = new Pair3<Long, Long, String>(startToken.lineNo, startToken.columnNo, 247 ModelBindingManager.getGlobalHash()); 248 this.endPosition = new Pair3<Long, Long, String>(endToken.lineNo, endToken.columnNo + SQLUtil.endTrim(endToken.astext).length(), 249 ModelBindingManager.getGlobalHash()); 250 } 251 252 // private int getIndexOf(TResultColumnList resultColumnList, 253 // TResultColumn resultColumnObject) { 254 // for (int i = 0; i < resultColumnList.size(); i++) { 255 // if (resultColumnList.getResultColumn(i) == resultColumnObject) 256 // return i; 257 // } 258 // return -1; 259 // } 260 261 public ResultSet getResultSet() { 262 return resultSet; 263 } 264 265 public long getId() { 266 return id; 267 } 268 269 public String getAlias() { 270 return alias; 271 } 272 273 public Pair3<Long, Long, String> getAliasStartPosition() { 274 return aliasStartPosition; 275 } 276 277 public Pair3<Long, Long, String> getAliasEndPosition() { 278 return aliasEndPosition; 279 } 280 281 public String getFullName() { 282 return fullName; 283 } 284 285 public Pair3<Long, Long, String> getStartPosition() { 286 return startPosition; 287 } 288 289 public Pair3<Long, Long, String> getEndPosition() { 290 return endPosition; 291 } 292 293 public TParseTreeNode getColumnObject() { 294 return columnObject; 295 } 296 297 public String getName() { 298 return name; 299 } 300 301 public boolean bindStarLinkColumn(TObjectName objectName) { 302 if (objectName == null) { 303 return false; 304 } 305 306 String columnName = DlineageUtil.getColumnName(objectName); 307 308 if ("*".equals(columnName)) { 309 return false; 310 } 311 312 boolean flag = false; 313 if (!starLinkColumns.containsKey(columnName)) { 314 starLinkColumns.put(columnName, new LinkedHashSet<TObjectName>()); 315 flag = true; 316 } 317 318 starLinkColumns.get(columnName).add(objectName); 319 320 if (this.getStarSourceColumns() != null) { 321 for (Column column : this.getStarSourceColumns()) { 322 boolean find = false; 323 if (column instanceof ResultColumn) { 324 ResultSet resultset = ((ResultColumn) column).getResultSet(); 325 for (ResultColumn resultColumn : resultset.getColumns()) { 326 if (DlineageUtil.compareColumnIdentifier(getColumnName(resultColumn.name), 327 getColumnName(objectName.toString()))) { 328 find = true; 329 break; 330 } 331 } 332 } 333 if (!find) { 334 column.bindStarLinkColumn(objectName); 335 } 336 } 337 } 338 339 return flag; 340 } 341 342 private String getColumnName(String column) { 343 if (column == null) { 344 return null; 345 } 346 String name = column.substring(column.lastIndexOf(".") + 1); 347 if (name == null || "".equals(name.trim())) { 348 return DlineageUtil.getIdentifierNormalColumnName(column.toString().trim()); 349 } else 350 return DlineageUtil.getIdentifierNormalColumnName(name.trim()); 351 } 352 353 354 public int indexOfStarLinkColumn(TObjectName objectName) { 355 if (objectName == null) { 356 return -1; 357 } 358 359 String columnName = DlineageUtil.getColumnName(objectName); 360 361 if ("*".equals(columnName)) { 362 return -1; 363 } 364 365 int index = -1; 366 for (String item : starLinkColumns.keySet()) { 367 index++; 368 if (item.equals(columnName)) { 369 return index; 370 } 371 } 372 return index; 373 } 374 375 public void unbindStarLinkColumn(TObjectName objectName) { 376 if (objectName == null) { 377 return; 378 } 379 380 String columnName = DlineageUtil.getColumnName(objectName); 381 starLinkColumns.remove(columnName); 382 } 383 384 public void bindStarLinkColumn(TObjectName objectName, int index) { 385 if (objectName == null) { 386 return; 387 } 388 389 String columnName = DlineageUtil.getColumnName(objectName); 390 391 if ("*".equals(columnName)) { 392 return; 393 } 394 if (!starLinkColumns.containsKey(columnName)) { 395 Map<String, Set<TObjectName>> copyStarLinkColumns = new LinkedHashMap<String, Set<TObjectName>>(); 396 int i = 0; 397 for(String item: starLinkColumns.keySet()){ 398 if(index == i){ 399 copyStarLinkColumns.put(columnName, new LinkedHashSet<TObjectName>()); 400 } 401 copyStarLinkColumns.put(item, starLinkColumns.get(item)); 402 i++; 403 } 404 starLinkColumns = copyStarLinkColumns; 405 } 406 407 if (starLinkColumns.get(columnName) != null) { 408 starLinkColumns.get(columnName).add(objectName); 409 } 410 else { 411 starLinkColumns.put(columnName, new LinkedHashSet<TObjectName>()); 412 starLinkColumns.get(columnName).add(objectName); 413 } 414 } 415 416 public boolean hasStarLinkColumn(){ 417 return starLinkColumns!=null && !starLinkColumns.isEmpty(); 418 } 419 420 public Map<String, Set<TObjectName>> getStarLinkColumns() { 421 return starLinkColumns; 422 } 423 424 public List<TObjectName> getStarLinkColumnList() { 425 List<TObjectName> columns = new ArrayList<TObjectName>(); 426 if (starLinkColumns != null) { 427 for (Set<TObjectName> columnSet : starLinkColumns.values()) { 428 columns.addAll(columnSet); 429 } 430 } 431 return columns; 432 } 433 434 public List<String> getStarLinkColumnNames() { 435 List<String> columns = new ArrayList<String>(); 436 if (starLinkColumns != null) { 437 columns.addAll(starLinkColumns.keySet()); 438 } 439 return columns; 440 } 441 442 public TObjectName getStarLinkColumnName(int index) { 443 List<String> columns = new ArrayList<String>(); 444 if (starLinkColumns != null) { 445 columns.addAll(starLinkColumns.keySet()); 446 } 447 return starLinkColumns.get(getStarLinkColumnNames().get(index)).iterator().next(); 448 } 449 450 public boolean isShowStar() { 451 return showStar; 452 } 453 454 public void setShowStar(boolean showStar) { 455 this.showStar = showStar; 456 } 457 458 public boolean isFunction() { 459 return isFunction; 460 } 461 462 public void setFunction(boolean isFunction) { 463 this.isFunction = isFunction; 464 } 465 466 public boolean isPseduo() { 467 return isPseduo; 468 } 469 470 public void setPseduo(boolean isPseduo) { 471 this.isPseduo = isPseduo; 472 } 473 474 public String getRefColumnName() { 475 return refColumnName; 476 } 477 478 @Override 479 public String toString() { 480 return this.name; 481 } 482 483 public boolean isStruct() { 484 return isStruct; 485 } 486 487 public void setStruct(boolean isStruct) { 488 this.isStruct = isStruct; 489 } 490 491 public Transform getTransform() { 492 return transform; 493 } 494 495 public void setTransform(Transform transform) { 496 this.transform = transform; 497 } 498}