in core/src/main/java/com/alibaba/druid/sql/repository/SchemaResolveVisitorFactory.java [1029:1236]
static void resolveIdent(SchemaResolveVisitor visitor, SQLIdentifierExpr x) {
SchemaResolveVisitor.Context ctx = visitor.getContext();
if (ctx == null) {
return;
}
String ident = x.getName();
long hash = x.nameHashCode64();
SQLTableSource tableSource = null;
if ((hash == FnvHash.Constants.LEVEL || hash == FnvHash.Constants.CONNECT_BY_ISCYCLE)
&& ctx.object instanceof SQLSelectQueryBlock) {
SQLSelectQueryBlock queryBlock = (SQLSelectQueryBlock) ctx.object;
if (queryBlock.getStartWith() != null
|| queryBlock.getConnectBy() != null) {
return;
}
}
SQLTableSource ctxTable = ctx.getTableSource();
if (ctxTable instanceof SQLJoinTableSource) {
SQLJoinTableSource join = (SQLJoinTableSource) ctxTable;
tableSource = join.findTableSourceWithColumn(hash, ident, visitor.getOptions());
if (tableSource == null) {
final SQLTableSource left = join.getLeft(), right = join.getRight();
if (left instanceof SQLSubqueryTableSource
&& right instanceof SQLExprTableSource) {
SQLSelect leftSelect = ((SQLSubqueryTableSource) left).getSelect();
if (leftSelect.getQuery() instanceof SQLSelectQueryBlock) {
boolean hasAllColumn = ((SQLSelectQueryBlock) leftSelect.getQuery()).selectItemHasAllColumn();
if (!hasAllColumn) {
tableSource = right;
}
}
} else if (right instanceof SQLSubqueryTableSource
&& left instanceof SQLExprTableSource) {
SQLSelect rightSelect = ((SQLSubqueryTableSource) right).getSelect();
if (rightSelect.getQuery() instanceof SQLSelectQueryBlock) {
boolean hasAllColumn = ((SQLSelectQueryBlock) rightSelect.getQuery()).selectItemHasAllColumn();
if (!hasAllColumn) {
tableSource = left;
}
}
} else if (left instanceof SQLExprTableSource && right instanceof SQLExprTableSource) {
SQLExprTableSource leftExprTableSource = (SQLExprTableSource) left;
SQLExprTableSource rightExprTableSource = (SQLExprTableSource) right;
if (leftExprTableSource.getSchemaObject() != null
&& rightExprTableSource.getSchemaObject() == null) {
tableSource = rightExprTableSource;
} else if (rightExprTableSource.getSchemaObject() != null
&& leftExprTableSource.getSchemaObject() == null) {
tableSource = leftExprTableSource;
}
}
}
} else if (ctxTable instanceof SQLSubqueryTableSource) {
tableSource = ctxTable.findTableSourceWithColumn(hash, ident, visitor.getOptions());
} else if (ctxTable instanceof SQLLateralViewTableSource) {
tableSource = ctxTable.findTableSourceWithColumn(hash, ident, visitor.getOptions());
if (tableSource == null) {
tableSource = ((SQLLateralViewTableSource) ctxTable).getTableSource();
}
} else {
for (SchemaResolveVisitor.Context parentCtx = ctx;
parentCtx != null;
parentCtx = parentCtx.parent) {
SQLDeclareItem declareItem = parentCtx.findDeclare(hash);
if (declareItem != null) {
x.setResolvedDeclareItem(declareItem);
return;
}
if (parentCtx.object instanceof SQLBlockStatement) {
SQLBlockStatement block = (SQLBlockStatement) parentCtx.object;
SQLParameter parameter = block.findParameter(hash);
if (parameter != null) {
x.setResolvedParameter(parameter);
return;
}
} else if (parentCtx.object instanceof SQLCreateProcedureStatement) {
SQLCreateProcedureStatement createProc = (SQLCreateProcedureStatement) parentCtx.object;
SQLParameter parameter = createProc.findParameter(hash);
if (parameter != null) {
x.setResolvedParameter(parameter);
return;
}
}
}
tableSource = ctxTable;
if (tableSource instanceof SQLExprTableSource) {
SchemaObject table = ((SQLExprTableSource) tableSource).getSchemaObject();
if (table != null) {
if (table.findColumn(hash) == null) {
SQLCreateTableStatement createStmt = null;
{
SQLStatement smt = table.getStatement();
if (smt instanceof SQLCreateTableStatement) {
createStmt = (SQLCreateTableStatement) smt;
}
}
if (createStmt != null && createStmt.getTableElementList().size() > 0) {
tableSource = null; // maybe parent
}
}
}
}
}
if (tableSource instanceof SQLExprTableSource) {
SQLExpr expr = ((SQLExprTableSource) tableSource).getExpr();
if (expr instanceof SQLMethodInvokeExpr) {
SQLMethodInvokeExpr func = (SQLMethodInvokeExpr) expr;
if (func.methodNameHashCode64() == FnvHash.Constants.ANN) {
expr = func.getArguments().get(0);
}
}
if (expr instanceof SQLIdentifierExpr) {
SQLIdentifierExpr identExpr = (SQLIdentifierExpr) expr;
long identHash = identExpr.nameHashCode64();
tableSource = unwrapAlias(ctx, tableSource, identHash);
}
}
if (tableSource != null) {
x.setResolvedTableSource(tableSource);
SQLObject column = tableSource.findColumn(hash);
if (column == null) {
column = tableSource.resolveColumn(hash);
}
if (column != null) {
x.setResolvedColumn(column);
}
if (ctxTable instanceof SQLJoinTableSource) {
String alias = tableSource.computeAlias();
if (alias == null || tableSource instanceof SQLWithSubqueryClause.Entry) {
return;
}
if (visitor.isEnabled(SchemaResolveVisitor.Option.ResolveIdentifierAlias)) {
SQLPropertyExpr propertyExpr = new SQLPropertyExpr(new SQLIdentifierExpr(alias), ident, hash);
propertyExpr.setResolvedColumn(x.getResolvedColumn());
propertyExpr.setResolvedTableSource(x.getResolvedTableSource());
SQLUtils.replaceInParent(x, propertyExpr);
}
}
}
if (x.getResolvedColumn() == null
&& x.getResolvedTableSource() == null) {
for (SchemaResolveVisitor.Context parentCtx = ctx;
parentCtx != null;
parentCtx = parentCtx.parent) {
SQLDeclareItem declareItem = parentCtx.findDeclare(hash);
if (declareItem != null) {
x.setResolvedDeclareItem(declareItem);
return;
}
if (parentCtx.object instanceof SQLBlockStatement) {
SQLBlockStatement block = (SQLBlockStatement) parentCtx.object;
SQLParameter parameter = block.findParameter(hash);
if (parameter != null) {
x.setResolvedParameter(parameter);
return;
}
} else if (parentCtx.object instanceof SQLCreateProcedureStatement) {
SQLCreateProcedureStatement createProc = (SQLCreateProcedureStatement) parentCtx.object;
SQLParameter parameter = createProc.findParameter(hash);
if (parameter != null) {
x.setResolvedParameter(parameter);
return;
}
}
}
}
if (x.getResolvedColumnObject() == null && ctx.object instanceof SQLSelectQueryBlock) {
SQLSelectQueryBlock queryBlock = (SQLSelectQueryBlock) ctx.object;
boolean having = false;
for (SQLObject current = x, parent = x.getParent(); parent != null; current = parent, parent = parent.getParent()) {
if (parent instanceof SQLSelectGroupByClause && parent.getParent() == queryBlock) {
SQLSelectGroupByClause groupBy = (SQLSelectGroupByClause) parent;
if (current == groupBy.getHaving()) {
having = true;
}
break;
}
}
if (having) {
SQLSelectItem selectItem = queryBlock.findSelectItem(x.hashCode64());
if (selectItem != null) {
x.setResolvedColumn(selectItem);
}
}
}
}