static void resolveIdent()

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);
                }
            }
        }
    }