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