001: /*
002: * Copyright (c) 1998 - 2005 Versant Corporation
003: * All rights reserved. This program and the accompanying materials
004: * are made available under the terms of the Eclipse Public License v1.0
005: * which accompanies this distribution, and is available at
006: * http://www.eclipse.org/legal/epl-v10.html
007: *
008: * Contributors:
009: * Versant Corporation - initial API and implementation
010: */
011: package com.versant.core.jdbc.sql.exp;
012:
013: import com.versant.core.jdbc.metadata.JdbcColumn;
014: import com.versant.core.jdbc.metadata.JdbcField;
015: import com.versant.core.jdbc.sql.SqlDriver;
016: import com.versant.core.util.CharBuf;
017: import com.versant.core.metadata.ClassMetaData;
018: import com.versant.core.jdo.query.ParamNode;
019: import com.versant.core.common.Debug;
020:
021: import java.util.Map;
022:
023: import com.versant.core.common.BindingSupportImpl;
024:
025: import javax.jdo.JDOFatalInternalException;
026:
027: /**
028: * The name of a column.
029: */
030: public class ColumnExp extends LeafExp {
031:
032: /**
033: * This may be null in which case this expression refers to all columns
034: * (i.e. a 'select *').
035: */
036: public JdbcColumn col;
037: /**
038: * The table this column belongs to. This provides the correct alias.
039: */
040: public SelectExp selectExp;
041: /**
042: * The field this expression is for (null if none).
043: */
044: public JdbcField jdbcField;
045: /**
046: * The class this expression is for (-1 if none).
047: */
048: public ClassMetaData cmd;
049:
050: private String asValue;
051:
052: public ColumnExp(JdbcColumn col, SelectExp selectExp,
053: JdbcField jdbcField) {
054: if (Debug.DEBUG) {
055: if (selectExp == null) {
056: throw BindingSupportImpl.getInstance().internal("");
057: }
058: if (col.table != selectExp.table) {
059: throw BindingSupportImpl
060: .getInstance()
061: .internal(
062: "The col for the table is not the same as the select exp");
063: }
064: }
065: this .col = col;
066: this .selectExp = selectExp;
067: this .jdbcField = jdbcField;
068: }
069:
070: public ColumnExp() {
071: }
072:
073: public ColumnExp(String asValue) {
074: if (asValue != null && asValue.length() > 0) {
075: this .asValue = asValue;
076: } else {
077: this .asValue = null;
078: }
079: }
080:
081: public SqlExp createInstance() {
082: return new ColumnExp();
083: }
084:
085: public SqlExp getClone(SqlExp columnExp, Map cloneMap) {
086: super .getClone(columnExp, cloneMap);
087: ColumnExp cst = (ColumnExp) columnExp;
088:
089: cst.col = col;
090: cst.jdbcField = jdbcField;
091: cst.cmd = cmd;
092: if (selectExp != null)
093: cst.selectExp = (SelectExp) createClone(selectExp, cloneMap);
094:
095: return columnExp;
096: }
097:
098: public ClassMetaData getCmd() {
099: return cmd;
100: }
101:
102: public void setCmd(ClassMetaData cmd) {
103: this .cmd = cmd;
104: }
105:
106: public String toString() {
107: return super .toString() + " " + col + " " + selectExp;
108: }
109:
110: /**
111: * Append SQL for this node to s.
112: *
113: * @param driver The driver being used
114: * @param s Append the SQL here
115: * @param leftSibling
116: */
117: public void appendSQLImp(SqlDriver driver, CharBuf s,
118: SqlExp leftSibling) {
119: if (isAliasedColumn() && jdbcField == null) {
120: s.append(" " + asValue + " ");
121: } else {
122: driver.appendSqlColumn(col, selectExp.alias, s);
123: if (isAliasedColumn()) {
124: s.append(driver.getAliasPrepend() + asValue);
125: }
126: }
127: }
128:
129: /**
130: * What is the JDBC type of this expression (0 if unknown)?
131: */
132: public int getJdbcType() {
133: return col.jdbcType;
134: }
135:
136: /**
137: * What is the java type code of this expression (0 if unknown)?
138: */
139: public int getJavaTypeCode() {
140: return col.javaTypeCode;
141: }
142:
143: /**
144: * What is the class index for this expression (-1 if unknown)?
145: * @see ParamNode
146: */
147: public int getClassIndex() {
148: if (cmd == null)
149: return -1;
150: else
151: return cmd.index;
152: }
153:
154: /**
155: * Replace any references to old with nw. This is used when redundant
156: * joins are removed.
157: */
158: public void replaceSelectExpRef(SelectExp old, SelectExp nw) {
159: if (nw == null) {
160: throw new JDOFatalInternalException();
161: }
162: if (selectExp == old) {
163: selectExp = nw;
164: } else {
165: SelectExp other = nw.findTableRecursive(selectExp.table,
166: selectExp.jdbcField);
167: if (other != null)
168: selectExp = other;
169: }
170: }
171:
172: /**
173: * If this expression involves a single table only then return the
174: * SelectExp for the table (e.g. a.col1 == 10 returns a, a.col1 = b.col2
175: * returns null). This is used to detect expressions that can be moved
176: * into the ON list for the join to the table involved.
177: * @param exclude
178: */
179: public SelectExp getSingleSelectExp(SelectExp exclude) {
180: return selectExp;
181: }
182:
183: /**
184: * Create an aliases for any subtables we may have.
185: */
186: public int createAlias(int index) {
187: if (selectExp == null)
188: return 0;
189: else
190: return selectExp.createAlias(index);
191: }
192:
193: public boolean isAliasedColumn() {
194: return asValue != null;
195: }
196:
197: public String getAsValue() {
198: return asValue;
199: }
200:
201: public void setColAlias(String columnAlias) {
202: if (columnAlias != null && columnAlias.length() > 0) {
203: this.asValue = columnAlias;
204: } else {
205: this.asValue = null;
206: }
207: }
208: }
|