| /* |
| * Copyright (c) 1998, 2020 Oracle and/or its affiliates. All rights reserved. |
| * |
| * This program and the accompanying materials are made available under the |
| * terms of the Eclipse Public License v. 2.0 which is available at |
| * http://www.eclipse.org/legal/epl-2.0, |
| * or the Eclipse Distribution License v. 1.0 which is available at |
| * http://www.eclipse.org/org/documents/edl-v10.php. |
| * |
| * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause |
| */ |
| |
| // Contributors: |
| // Oracle - initial API and implementation from Oracle TopLink |
| package org.eclipse.persistence.internal.expressions; |
| |
| import java.io.*; |
| import java.util.*; |
| |
| import org.eclipse.persistence.internal.helper.*; |
| import org.eclipse.persistence.expressions.*; |
| |
| /** |
| * A TableExpression allows for a raw database table to be referenced in a query. |
| * This is used for ManyToMany and DirectCollection mappings to define their selection criteria. |
| * It can also be used directly to mix SQL artifacts with Expressions. |
| */ |
| public class TableExpression extends DataExpression { |
| protected DatabaseTable table; |
| |
| public TableExpression() { |
| super(); |
| } |
| |
| public TableExpression(DatabaseTable table) { |
| super(); |
| this.table = table; |
| } |
| |
| /** |
| * INTERNAL: |
| * Alias a particular table within this node |
| */ |
| @Override |
| protected void assignAlias(DatabaseTable alias, DatabaseTable table) { |
| if (this.baseExpression.isQueryKeyExpression()){ |
| QueryKeyExpression qkExpression = ((QueryKeyExpression)this.baseExpression); |
| if (qkExpression.getTableAliases() != null && qkExpression.getTableAliases().keyAtValue(table) != null ) { |
| return; |
| } |
| } |
| super.assignAlias(alias, table); |
| } |
| |
| /** |
| * INTERNAL: |
| * Return if the expression is equal to the other. |
| * This is used to allow dynamic expression's SQL to be cached. |
| */ |
| @Override |
| public boolean equals(Object object) { |
| if (this == object) { |
| return true; |
| } |
| if (!super.equals(object)) { |
| return false; |
| } |
| TableExpression expression = (TableExpression) object; |
| return ((this.table == expression.table) || ((this.table != null) && this.table.equals(expression.table))); |
| } |
| |
| /** |
| * INTERNAL: |
| * Compute a consistent hash-code for the expression. |
| * This is used to allow dynamic expression's SQL to be cached. |
| */ |
| @Override |
| public int computeHashCode() { |
| int hashCode = super.computeHashCode(); |
| if (getTable() != null) { |
| hashCode = hashCode + getTable().hashCode(); |
| } |
| return hashCode; |
| } |
| |
| /** |
| * INTERNAL: |
| * Used for debug printing. |
| */ |
| @Override |
| public String descriptionOfNodeType() { |
| return "Table"; |
| } |
| |
| /** |
| * INTERNAL: |
| * Fully-qualify the databaseField if the table is known. |
| * CR 3791 |
| */ |
| @Override |
| public Expression getField(String fieldName) { |
| // we need to check for full table qualification |
| DatabaseField field = new DatabaseField(fieldName); |
| if (!field.hasTableName()) { |
| field.setTable(getTable()); |
| } |
| return getField(field); |
| } |
| |
| /** |
| * INTERNAL: |
| */ |
| @Override |
| public List<DatabaseTable> getOwnedTables() { |
| List<DatabaseTable> result = new ArrayList(1); |
| result.add(getTable()); |
| return result; |
| } |
| |
| public DatabaseTable getTable() { |
| return table; |
| } |
| |
| @Override |
| public boolean isTableExpression() { |
| return true; |
| } |
| |
| /** |
| * INTERNAL: |
| * Normalize the expression into a printable structure. |
| * Any joins must be added to form a new root. |
| */ |
| @Override |
| public Expression normalize(ExpressionNormalizer normalizer) { |
| if (this.hasBeenNormalized) { |
| return this; |
| } |
| // Bug4736461 Only setTableQualifier if getDatasourceLogin().getTableQualifier() is an empty string to make the window much smaller when |
| // DatabaseTable.qualifiedName is reset |
| if (getTable().getTableQualifier().length() == 0 && (normalizer.getSession().getDatasourceLogin().getTableQualifier().length() != 0)) { |
| getTable().setTableQualifier(normalizer.getSession().getDatasourceLogin().getTableQualifier()); |
| } |
| return super.normalize(normalizer); |
| } |
| |
| /** |
| * INTERNAL: |
| * This expression is built on a different base than the one we want. Rebuild it and |
| * return the root of the new tree |
| */ |
| @Override |
| public Expression rebuildOn(Expression newBase) { |
| Expression newLocalBase = getBaseExpression().rebuildOn(newBase); |
| return newLocalBase.getTable(getTable()); |
| } |
| |
| /** |
| * INTERNAL: |
| * Added for temporal querying. |
| */ |
| public void setTable(DatabaseTable table) { |
| this.table = table; |
| } |
| |
| /** |
| * INTERNAL: |
| * Rebuild myself against the base, with the values of parameters supplied by the context |
| * expression. This is used for transforming a standalone expression (e.g. the join criteria of a mapping) |
| * into part of some larger expression. You normally would not call this directly, instead calling twist |
| * See the comment there for more details" |
| */ |
| @Override |
| public Expression twistedForBaseAndContext(Expression newBase, Expression context, Expression oldBase) { |
| Expression twistedBase = getBaseExpression().twistedForBaseAndContext(newBase, context, oldBase); |
| return twistedBase.getTable(getTable()); |
| } |
| |
| /** |
| * INTERNAL: |
| * Used to print a debug form of the expression tree. |
| */ |
| @Override |
| public void writeDescriptionOn(BufferedWriter writer) throws IOException { |
| writer.write(getTable().toString()); |
| writer.write(tableAliasesDescription()); |
| } |
| } |