You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@openjpa.apache.org by pc...@apache.org on 2006/07/19 23:35:07 UTC
svn commit: r423615 [9/44] - in /incubator/openjpa/trunk: ./ openjpa-jdbc-5/
openjpa-jdbc-5/src/ openjpa-jdbc-5/src/main/ openjpa-jdbc-5/src/main/java/
openjpa-jdbc-5/src/main/java/org/ openjpa-jdbc-5/src/main/java/org/apache/
openjpa-jdbc-5/src/main/j...
Added: incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/PCPath.java
URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/PCPath.java?rev=423615&view=auto
==============================================================================
--- incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/PCPath.java (added)
+++ incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/PCPath.java Wed Jul 19 14:34:44 2006
@@ -0,0 +1,633 @@
+/*
+ * Copyright 2006 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.openjpa.jdbc.kernel.exps;
+
+import java.sql.SQLException;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.ListIterator;
+
+import org.apache.openjpa.jdbc.kernel.JDBCFetchConfiguration;
+import org.apache.openjpa.jdbc.kernel.JDBCFetchState;
+import org.apache.openjpa.jdbc.kernel.JDBCStore;
+import org.apache.openjpa.jdbc.meta.ClassMapping;
+import org.apache.openjpa.jdbc.meta.FieldMapping;
+import org.apache.openjpa.jdbc.meta.ValueMapping;
+import org.apache.openjpa.jdbc.schema.Column;
+import org.apache.openjpa.jdbc.schema.Schemas;
+import org.apache.openjpa.jdbc.sql.Joins;
+import org.apache.openjpa.jdbc.sql.Result;
+import org.apache.openjpa.jdbc.sql.SQLBuffer;
+import org.apache.openjpa.jdbc.sql.Select;
+import org.apache.openjpa.kernel.Filters;
+import org.apache.openjpa.lib.util.Localizer;
+import org.apache.openjpa.meta.ClassMetaData;
+import org.apache.openjpa.meta.FieldMetaData;
+import org.apache.openjpa.meta.JavaTypes;
+import org.apache.openjpa.util.UserException;
+
+/**
+ * A path represents a traversal into fields of a candidate object.
+ *
+ * @author Abe White
+ */
+class PCPath
+ implements JDBCPath {
+
+ private static final int PATH = 0;
+ private static final int BOUND_VAR = 1;
+ private static final int UNBOUND_VAR = 2;
+ private static final int UNACCESSED_VAR = 3;
+
+ private static final Localizer _loc = Localizer.forPackage(PCPath.class);
+
+ private final ClassMapping _candidate;
+ private LinkedList _actions = null;
+ private Joins _joins = null;
+ private boolean _forceOuter = false;
+ private ClassMapping _class = null;
+ private FieldMapping _field = null;
+ private boolean _key = false;
+ private boolean _joinedRel = false;
+ private int _type = PATH;
+ private String _varName = null;
+ private Column[] _cols = null;
+ private Class _cast = null;
+
+ /**
+ * Return a path starting with the 'this' ptr.
+ */
+ public PCPath(ClassMapping type) {
+ _candidate = type;
+ }
+
+ /**
+ * Return a path starting from the given variable.
+ */
+ public PCPath(ClassMapping candidate, Variable var) {
+ _candidate = candidate;
+ _actions = new LinkedList();
+
+ PCPath other = var.getPCPath();
+ Action action = new Action();
+ if (other == null) {
+ _type = UNBOUND_VAR;
+ action.op = Action.UNBOUND_VAR;
+ action.data = var;
+ } else {
+ // bound variable; copy path
+ _type = UNACCESSED_VAR;
+ _actions.addAll(other._actions);
+
+ action.op = Action.VAR;
+ action.data = var.getName();
+ }
+ _actions.add(action);
+ _cast = var.getType(); // initial type is var type
+ }
+
+ /**
+ * Return a path starting from the given subquery.
+ */
+ public PCPath(SubQ sub) {
+ _candidate = sub.getCandidate();
+ _actions = new LinkedList();
+
+ Action action = new Action();
+ action.op = Action.SUBQUERY;
+ action.data = sub.getCandidateAlias();
+ _actions.add(action);
+ _cast = sub.getType(); // initial type is subquery type
+ _varName = sub.getCandidateAlias();
+ }
+
+ /**
+ * Set the path as a binding of the given variable.
+ */
+ public void addVariableAction(Variable var) {
+ _varName = var.getName();
+ }
+
+ /**
+ * Return true if this is a bound variable that has not been accessed
+ * after binding. Useful for filters like
+ * "coll.contains (var) && var == null", which should really
+ * just act like "coll.contains (null)".
+ */
+ public boolean isUnaccessedVariable() {
+ return _type == UNACCESSED_VAR;
+ }
+
+ /**
+ * If this path is part of a contains clause, then alias it to the
+ * proper contains id before initialization.
+ */
+ public void setContainsId(String id) {
+ // treat it just like a unique variable
+ Action action = new Action();
+ action.op = Action.VAR;
+ action.data = id;
+ if (_actions == null)
+ _actions = new LinkedList();
+ _actions.add(action);
+ }
+
+ public ClassMetaData getMetaData() {
+ return _class;
+ }
+
+ public void setMetaData(ClassMetaData meta) {
+ _class = (ClassMapping) meta;
+ }
+
+ public boolean isVariable() {
+ return false;
+ }
+
+ public ClassMapping getClassMapping() {
+ if (_field == null)
+ return _class;
+ if (_key) {
+ if (_field.getKey().getTypeCode() == JavaTypes.PC)
+ return _field.getKeyMapping().getTypeMapping();
+ return null;
+ }
+ if (_field.getElement().getTypeCode() == JavaTypes.PC)
+ return _field.getElementMapping().getTypeMapping();
+ if (_field.getTypeCode() == JavaTypes.PC)
+ return _field.getTypeMapping();
+ return null;
+ }
+
+ public FieldMapping getFieldMapping() {
+ return _field;
+ }
+
+ public boolean isKey() {
+ return _key;
+ }
+
+ public String getPath() {
+ if (_actions == null)
+ return (_varName == null) ? "" : _varName + ".";
+
+ StringBuffer path = new StringBuffer();
+ Action action;
+ for (Iterator itr = _actions.iterator(); itr.hasNext();) {
+ action = (Action) itr.next();
+ if (action.op == Action.VAR || action.op == Action.SUBQUERY)
+ path.append(action.data);
+ else if (action.op == Action.UNBOUND_VAR)
+ path.append(((Variable) action.data).getName());
+ else
+ path.append(((FieldMapping) action.data).getName());
+ path.append('.');
+ }
+ if (_varName != null)
+ path.append(_varName).append('.');
+ return path.toString();
+ }
+
+ public Column[] getColumns() {
+ if (_cols == null)
+ _cols = calculateColumns();
+ return _cols;
+ }
+
+ /**
+ * The columns used by this path.
+ */
+ private Column[] calculateColumns() {
+ if (_key) {
+ if (!_joinedRel && _field.getKey().getValueMappedBy() != null)
+ joinRelation();
+ else if (_joinedRel
+ && _field.getKey().getTypeCode() == JavaTypes.PC)
+ return _field.getKeyMapping().getTypeMapping().
+ getPrimaryKeyColumns();
+ return _field.getKeyMapping().getColumns();
+ }
+ if (_field != null) {
+ switch (_field.getTypeCode()) {
+ case JavaTypes.MAP:
+ case JavaTypes.ARRAY:
+ case JavaTypes.COLLECTION:
+ ValueMapping elem = _field.getElementMapping();
+ if (_joinedRel && elem.getTypeCode() == JavaTypes.PC)
+ return elem.getTypeMapping().getPrimaryKeyColumns();
+ if (elem.getColumns().length > 0)
+ return elem.getColumns();
+ return _field.getColumns();
+ case JavaTypes.PC:
+ if (_joinedRel)
+ return _field.getTypeMapping().getPrimaryKeyColumns();
+ return _field.getColumns();
+ default:
+ return _field.getColumns();
+ }
+ }
+ return (_class == null) ? Schemas.EMPTY_COLUMNS
+ : _class.getPrimaryKeyColumns();
+ }
+
+ public void get(FieldMetaData field, boolean nullTraversal) {
+ if (_actions == null)
+ _actions = new LinkedList();
+ Action action = new Action();
+ action.op = (nullTraversal) ? Action.GET_OUTER : Action.GET;
+ action.data = field;
+ _actions.add(action);
+ if (_type == UNACCESSED_VAR)
+ _type = BOUND_VAR;
+ _cast = null;
+ }
+
+ public void getKey() {
+ // change the last action to a get key
+ Action action = (Action) _actions.getLast();
+ action.op = Action.GET_KEY;
+ _cast = null;
+ }
+
+ public FieldMetaData last() {
+ Action act = lastFieldAction();
+ return (act == null) ? null : (FieldMetaData) act.data;
+ }
+
+ /**
+ * Return the last action that gets a field.
+ */
+ private Action lastFieldAction() {
+ if (_actions == null)
+ return null;
+
+ ListIterator itr = _actions.listIterator(_actions.size());
+ Action prev;
+ while (itr.hasPrevious()) {
+ prev = (Action) itr.previous();
+ if (prev.op == Action.GET || prev.op == Action.GET_OUTER
+ || prev.op == Action.GET_KEY)
+ return prev;
+
+ // break if we're getting to path portions that we copied from
+ // our variable
+ if (prev.op == Action.VAR || prev.op == Action.UNBOUND_VAR
+ || prev.op == Action.SUBQUERY)
+ break;
+ }
+ return null;
+ }
+
+ public Class getType() {
+ if (_cast != null)
+ return _cast;
+ FieldMetaData fld;
+ boolean key;
+ if (_field != null) {
+ fld = _field;
+ key = _key;
+ } else {
+ Action act = lastFieldAction();
+ fld = (act == null) ? null : (FieldMetaData) act.data;
+ key = act != null && act.op == Action.GET_KEY;
+ }
+
+ if (fld != null) {
+ switch (fld.getDeclaredTypeCode()) {
+ case JavaTypes.MAP:
+ if (key)
+ return fld.getKey().getDeclaredType();
+ // no break
+ case JavaTypes.ARRAY:
+ case JavaTypes.COLLECTION:
+ return fld.getElement().getDeclaredType();
+ default:
+ return fld.getDeclaredType();
+ }
+ }
+ if (_class != null)
+ return _class.getDescribedType();
+ return Object.class;
+ }
+
+ public void setImplicitType(Class type) {
+ _cast = type;
+ }
+
+ public void initialize(Select sel, JDBCStore store, boolean nullTest) {
+ // initialize can be called more than once, so reset
+ _field = null;
+ _key = false;
+ _forceOuter = false;
+ _joinedRel = false;
+ _joins = sel.newJoins();
+
+ // iterate to the final field
+ ClassMapping rel = _candidate;
+ ClassMapping owner;
+ ClassMapping from, to;
+ Action action;
+ Variable var;
+ Iterator itr = (_actions == null) ? null : _actions.iterator();
+ while (itr != null && itr.hasNext()) {
+ action = (Action) itr.next();
+
+ // treat subqueries like variables for alias generation purposes
+ if (action.op == Action.VAR)
+ _joins = _joins.setVariable((String) action.data);
+ else if (action.op == Action.SUBQUERY)
+ _joins = _joins.setSubselect((String) action.data);
+ else if (action.op == Action.UNBOUND_VAR) {
+ // unbound vars are cross-joined to the candidate table
+ var = (Variable) action.data;
+ rel = (ClassMapping) var.getMetaData();
+ _joins = _joins.setVariable(var.getName());
+ _joins = _joins.crossJoin(_candidate.getTable(),
+ rel.getTable());
+ } else {
+ // move past the previous field, if any
+ if (_field != null)
+ rel = traverseField(false);
+
+ // mark if the next traversal should go through
+ // the key rather than value
+ _key = action.op == Action.GET_KEY;
+ _forceOuter |= action.op == Action.GET_OUTER;
+
+ // get mapping for the current field
+ _field = (FieldMapping) action.data;
+ owner = _field.getDefiningMapping();
+ if (_field.getManagement() != FieldMapping.MANAGE_PERSISTENT)
+ throw new UserException(_loc.get("non-pers-field",
+ _field));
+
+ // find the most-derived type between the declared relation
+ // type and the field's owner, and join from that type to
+ // the lesser derived type
+ if (rel != owner && rel != null) {
+ if (rel.getDescribedType().isAssignableFrom
+ (owner.getDescribedType())) {
+ from = owner;
+ to = rel;
+ } else {
+ from = rel;
+ to = owner;
+ }
+
+ for (; from != null && from != to;
+ from = from.getJoinablePCSuperclassMapping())
+ _joins = from.joinSuperclass(_joins, false);
+ }
+ }
+ }
+ if (_varName != null)
+ _joins = _joins.setVariable(_varName);
+
+ // if we're not comparing to null or doing an isEmpty, then
+ // join into the data on the final field; obviously we can't do these
+ // joins when comparing to null b/c the whole purpose is to see
+ // whether the joins even exist
+ if (!nullTest)
+ traverseField(true);
+
+ // note that we haven't yet joined to the relation of the last field yet
+ _joinedRel = false;
+ }
+
+ /**
+ * Traverse into the previous field of a relation path.
+ *
+ * @param last whether this is the last field in the path
+ * @return the mapping of the related type, or null
+ */
+ private ClassMapping traverseField(boolean last) {
+ if (_field == null)
+ return null;
+
+ // traverse into field value
+ if (_key)
+ _joins = _field.joinKey(_joins, _forceOuter);
+ else
+ _joins = _field.join(_joins, _forceOuter);
+
+ // if this isn't the last field, traverse into the relation
+ if (!last)
+ joinRelation(true);
+
+ // return the maping of the related type, if any
+ if (_key)
+ return _field.getKeyMapping().getTypeMapping();
+ if (_field.getElement().getTypeCode() == JavaTypes.PC)
+ return _field.getElementMapping().getTypeMapping();
+ return _field.getTypeMapping();
+ }
+
+ /**
+ * Join into the relation represented by the current field, if any.
+ */
+ void joinRelation() {
+ joinRelation(false);
+ }
+
+ private void joinRelation(boolean traverse) {
+ if (_field == null)
+ return;
+ if (_key)
+ _joins = _field.joinKeyRelation(_joins, _forceOuter, traverse);
+ else
+ _joins = _field.joinRelation(_joins, _forceOuter, traverse);
+ _joinedRel = true;
+ }
+
+ public Joins getJoins() {
+ return _joins;
+ }
+
+ public Object toDataStoreValue(Object val, JDBCStore store) {
+ if (_field != null) {
+ if (_key)
+ return _field.toKeyDataStoreValue(val, store);
+ if (_field.getElement().getDeclaredTypeCode() != JavaTypes.OBJECT)
+ return _field.toDataStoreValue(val, store);
+
+ val = _field.getExternalValue(val, store.getContext());
+ return _field.toDataStoreValue(val, store);
+ }
+ return _class.toDataStoreValue(val, _class.getPrimaryKeyColumns(),
+ store);
+ }
+
+ public void select(Select sel, JDBCStore store, Object[] params,
+ boolean pks, JDBCFetchState fetchState) {
+ selectColumns(sel, store, params, pks, fetchState);
+ }
+
+ public void selectColumns(Select sel, JDBCStore store,
+ Object[] params, boolean pks, JDBCFetchState fetchState) {
+ ClassMapping mapping = getClassMapping();
+ if (mapping == null || !_joinedRel)
+ sel.select(getColumns(), _joins);
+ else if (pks)
+ sel.select(mapping.getPrimaryKeyColumns(), _joins);
+ else {
+ // select the mapping; allow any subs because we know this must
+ // be either a relation, in which case it will already be
+ // constrained by the joins, or 'this', in which case the
+ // JDBCExpressionFactory takes care of adding class conditions for
+ // the candidate class on the select
+ int subs = (_type == UNBOUND_VAR) ? sel.SUBS_JOINABLE
+ : sel.SUBS_ANY_JOINABLE;
+ sel.select(mapping, subs, store, fetchState,
+ JDBCFetchConfiguration.EAGER_NONE, sel.outer(_joins));
+ }
+ }
+
+ public void groupBy(Select sel, JDBCStore store, Object[] params,
+ JDBCFetchState fetchState) {
+ sel.groupBy(getColumns(), sel.outer(_joins), false);
+ }
+
+ public void orderBy(Select sel, JDBCStore store, Object[] params,
+ boolean asc, JDBCFetchState fetchState) {
+ sel.orderBy(getColumns(), asc, sel.outer(_joins), false);
+ }
+
+ public Object load(Result res, JDBCStore store,
+ JDBCFetchState fetchState)
+ throws SQLException {
+ return load(res, store, false, fetchState);
+ }
+
+ Object load(Result res, JDBCStore store, boolean pks,
+ JDBCFetchState fetchState)
+ throws SQLException {
+ ClassMapping mapping = getClassMapping();
+ if (mapping != null && (_field == null || !_field.isEmbedded())) {
+ if (pks)
+ return mapping.getObjectId(store, res, null, true, _joins);
+ return res.load(mapping, store, fetchState, _joins);
+ }
+
+ Object ret;
+ if (_key)
+ ret = _field.loadKeyProjection(store, fetchState, res, _joins);
+ else
+ ret = _field.loadProjection(store, fetchState, res, _joins);
+ if (_cast != null)
+ ret = Filters.convert(ret, _cast);
+ return ret;
+ }
+
+ public boolean hasVariable(Variable var) {
+ if (_actions == null)
+ return false;
+
+ Action action;
+ for (Iterator itr = _actions.iterator(); itr.hasNext();) {
+ action = (Action) itr.next();
+ if (action.op == Action.VAR && action.data.equals(var.getName()))
+ return true;
+ }
+ return false;
+ }
+
+ public void calculateValue(Select sel, JDBCStore store,
+ Object[] params, Val other, JDBCFetchState fetchState) {
+ // we don't create the SQL b/c it forces the Select to cache aliases
+ // for the tables we use, and these aliases might not ever be used if
+ // we eventually call appendIsEmpty or appendIsNull rather than appendTo
+ }
+
+ public void clearParameters() {
+ }
+
+ public int length() {
+ return getColumns().length;
+ }
+
+ public void appendTo(SQLBuffer sql, int index, Select sel,
+ JDBCStore store, Object[] params, JDBCFetchState fetchState) {
+ Column col = getColumns()[index];
+
+ // if select is null, it means we are not aliasing columns
+ // (e.g., during a bulk update)
+ if (sel == null)
+ sql.append(col.getName());
+ else
+ sql.append(sel.getColumnAlias(col, _joins));
+ }
+
+ public void appendIsEmpty(SQLBuffer sql, Select sel,
+ JDBCStore store, Object[] params, JDBCFetchState fetchState) {
+ if (_field == null)
+ sql.append("1 <> 1");
+ else
+ _field.appendIsEmpty(sql, sel, _joins);
+ }
+
+ public void appendIsNotEmpty(SQLBuffer sql, Select sel,
+ JDBCStore store, Object[] params, JDBCFetchState fetchState) {
+ if (_field == null)
+ sql.append("1 <> 1");
+ else
+ _field.appendIsNotEmpty(sql, sel, _joins);
+ }
+
+ public void appendSize(SQLBuffer sql, Select sel, JDBCStore store,
+ Object[] params, JDBCFetchState fetchState) {
+ if (_field == null)
+ sql.append("1");
+ else
+ _field.appendSize(sql, sel, _joins);
+ }
+
+ public void appendIsNull(SQLBuffer sql, Select sel,
+ JDBCStore store, Object[] params, JDBCFetchState fetchState) {
+ if (_field == null)
+ sql.append("1 <> 1");
+ else
+ _field.appendIsNull(sql, sel, _joins);
+ }
+
+ public void appendIsNotNull(SQLBuffer sql, Select sel,
+ JDBCStore store, Object[] params, JDBCFetchState fetchState) {
+ if (_field == null)
+ sql.append("1 = 1");
+ else
+ _field.appendIsNotNull(sql, sel, _joins);
+ }
+
+ /**
+ * Helper class representing an action.
+ */
+ private static class Action {
+
+ public static final int GET = 0;
+ public static final int GET_OUTER = 1;
+ public static final int GET_KEY = 2;
+ public static final int VAR = 3;
+ public static final int SUBQUERY = 4;
+ public static final int UNBOUND_VAR = 5;
+ public static final int CAST = 6;
+
+ public int op = -1;
+ public Object data = null;
+
+ public String toString() {
+ return op + "|" + data;
+ }
+ }
+}
Propchange: incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/PCPath.java
------------------------------------------------------------------------------
svn:executable = *
Added: incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/Param.java
URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/Param.java?rev=423615&view=auto
==============================================================================
--- incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/Param.java (added)
+++ incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/Param.java Wed Jul 19 14:34:44 2006
@@ -0,0 +1,117 @@
+/*
+ * Copyright 2006 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.openjpa.jdbc.kernel.exps;
+
+import java.util.Collection;
+import java.util.Map;
+
+import org.apache.openjpa.jdbc.kernel.JDBCFetchState;
+import org.apache.openjpa.jdbc.kernel.JDBCStore;
+import org.apache.openjpa.jdbc.sql.SQLBuffer;
+import org.apache.openjpa.jdbc.sql.Select;
+import org.apache.openjpa.kernel.Filters;
+import org.apache.openjpa.kernel.exps.Parameter;
+import org.apache.openjpa.util.ImplHelper;
+
+/**
+ * A parameter in a filter.
+ *
+ * @author Abe White
+ */
+class Param
+ extends Const
+ implements Parameter {
+
+ private final String _name;
+ private Class _type = null;
+ private int _idx = -1;
+ private boolean _container = false;
+ private Object _val = null;
+ private Object _sqlVal = null;
+ private int _otherLen = 0;
+
+ /**
+ * Constructor. Supply parameter name and type.
+ */
+ public Param(String name, Class type) {
+ _name = name;
+ setImplicitType(type);
+ }
+
+ public String getName() {
+ return _name;
+ }
+
+ public String getParameterName() {
+ return getName();
+ }
+
+ public Class getType() {
+ return _type;
+ }
+
+ public void setImplicitType(Class type) {
+ _type = type;
+ _container = (getMetaData() == null ||
+ !ImplHelper.isManagedType(type))
+ && (Collection.class.isAssignableFrom(type)
+ || Map.class.isAssignableFrom(type));
+ }
+
+ public int getIndex() {
+ return _idx;
+ }
+
+ public void setIndex(int idx) {
+ _idx = idx;
+ }
+
+ public Object getValue() {
+ return _val;
+ }
+
+ public Object getSQLValue() {
+ return _sqlVal;
+ }
+
+ public Object getValue(Object[] params) {
+ return params[_idx];
+ }
+
+ public void calculateValue(Select sel, JDBCStore store,
+ Object[] params, Val other, JDBCFetchState fetchState) {
+ super.calculateValue(sel, store, params, other, fetchState);
+ _val = Filters.convert(params[_idx], getType());
+ if (other != null && !_container) {
+ _sqlVal = other.toDataStoreValue(_val, store);
+ _otherLen = other.length();
+ } else
+ _sqlVal = _val;
+ }
+
+ public void appendTo(SQLBuffer sql, int index, Select sel,
+ JDBCStore store, Object[] params, JDBCFetchState fetchState) {
+ if (_otherLen > 1)
+ sql.appendValue(((Object[]) _sqlVal)[index], getColumn(index));
+ else
+ sql.appendValue(_sqlVal, getColumn(index));
+ }
+
+ public void clearParameters() {
+ _val = null;
+ _sqlVal = null;
+ }
+}
Propchange: incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/Param.java
------------------------------------------------------------------------------
svn:executable = *
Added: incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/SQLEmbed.java
URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/SQLEmbed.java?rev=423615&view=auto
==============================================================================
--- incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/SQLEmbed.java (added)
+++ incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/SQLEmbed.java Wed Jul 19 14:34:44 2006
@@ -0,0 +1,69 @@
+/*
+ * Copyright 2006 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.openjpa.jdbc.kernel.exps;
+
+import org.apache.openjpa.jdbc.kernel.JDBCStore;
+import org.apache.openjpa.jdbc.meta.ClassMapping;
+import org.apache.openjpa.jdbc.sql.SQLBuffer;
+import org.apache.openjpa.kernel.StoreContext;
+import org.apache.openjpa.lib.util.Localizer;
+import org.apache.openjpa.util.UnsupportedException;
+import org.apache.openjpa.util.UserException;
+
+/**
+ * Simple listener which embeds its SQL argument into the query. Listens
+ * on <code>sql</code>.
+ * Example:<br />
+ * <code> "price < sql(\"(SELECT AVG (PRICE) FROM PRODUCT_TABLE)\")"
+ * </code>
+ *
+ * @nojavadoc
+ */
+public class SQLEmbed
+ implements JDBCFilterListener {
+
+ public static String TAG = "sql";
+
+ private static final Localizer _loc = Localizer.forPackage(SQLEmbed.class);
+
+ public String getTag() {
+ return TAG;
+ }
+
+ public boolean expectsArguments() {
+ return true;
+ }
+
+ public boolean expectsTarget() {
+ return false;
+ }
+
+ public Object evaluate(Object target, Class targetClass, Object[] args,
+ Class[] argClasses, Object candidate, StoreContext ctx) {
+ throw new UnsupportedException(_loc.get("no-in-mem", TAG));
+ }
+
+ public void appendTo(SQLBuffer buf, FilterValue target, FilterValue[] args,
+ ClassMapping type, JDBCStore store) {
+ if (!args[0].isConstant())
+ throw new UserException(_loc.get("const-only", TAG));
+ buf.append(args[0].getValue().toString());
+ }
+
+ public Class getType(Class targetClass, Class[] argClasses) {
+ return Object.class;
+ }
+}
Propchange: incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/SQLEmbed.java
------------------------------------------------------------------------------
svn:executable = *
Added: incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/SQLExpression.java
URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/SQLExpression.java?rev=423615&view=auto
==============================================================================
--- incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/SQLExpression.java (added)
+++ incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/SQLExpression.java Wed Jul 19 14:34:44 2006
@@ -0,0 +1,38 @@
+/*
+ * Copyright 2006 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.openjpa.jdbc.kernel.exps;
+
+/**
+ * Simple listener which embeds the argument as an expression into the
+ * where clause generated by the query. Listens on "ext:sqlExp".
+ * Example:<br />
+ * <code>
+ * "price < 10 || ext:sqlExp (\"(SELECT AVG (PRICE) FROM PRODUCT_TABLE)
+ * > 100\")"
+ * </code>
+ *
+ * @nojavadoc
+ * @deprecated Use {@link SQLEmbed} directly
+ */
+public class SQLExpression
+ extends SQLEmbed {
+
+ public static final String TAG = "sqlExp";
+
+ public String getTag() {
+ return TAG;
+ }
+}
Propchange: incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/SQLExpression.java
------------------------------------------------------------------------------
svn:executable = *
Added: incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/SQLValue.java
URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/SQLValue.java?rev=423615&view=auto
==============================================================================
--- incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/SQLValue.java (added)
+++ incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/SQLValue.java Wed Jul 19 14:34:44 2006
@@ -0,0 +1,36 @@
+/*
+ * Copyright 2006 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.openjpa.jdbc.kernel.exps;
+
+/**
+ * Simple listener which embeds the argument as a value into the where
+ * clause generated by the query. Listens on "ext:sqlVal".
+ * Example:<br />
+ * <code> "price < ext:sqlVal (\"(SELECT AVG (PRICE) FROM PRODUCT_TABLE)\")"
+ * </code>
+ *
+ * @nojavadoc
+ * @deprecated Use {@link SQLEmbed} directly
+ */
+public class SQLValue
+ extends SQLEmbed {
+
+ public static final String TAG = "sqlVal";
+
+ public String getTag() {
+ return TAG;
+ }
+}
Propchange: incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/SQLValue.java
------------------------------------------------------------------------------
svn:executable = *
Added: incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/SelectConstructor.java
URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/SelectConstructor.java?rev=423615&view=auto
==============================================================================
--- incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/SelectConstructor.java (added)
+++ incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/SelectConstructor.java Wed Jul 19 14:34:44 2006
@@ -0,0 +1,352 @@
+/*
+ * Copyright 2006 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.openjpa.jdbc.kernel.exps;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.openjpa.jdbc.kernel.JDBCFetchConfiguration;
+import org.apache.openjpa.jdbc.kernel.JDBCFetchState;
+import org.apache.openjpa.jdbc.kernel.JDBCStore;
+import org.apache.openjpa.jdbc.meta.ClassMapping;
+import org.apache.openjpa.jdbc.sql.DBDictionary;
+import org.apache.openjpa.jdbc.sql.Joins;
+import org.apache.openjpa.jdbc.sql.SQLBuffer;
+import org.apache.openjpa.jdbc.sql.Select;
+import org.apache.openjpa.kernel.exps.Expression;
+import org.apache.openjpa.kernel.exps.QueryExpressions;
+
+/**
+ * Turns parsed queries into selects.
+ *
+ * @author Abe White
+ */
+class SelectConstructor {
+
+ public static final int CACHE_NULL = 0;
+ public static final int CACHE_JOINS = 1;
+ public static final int CACHE_FULL = 2;
+
+ // cache as much as we can for multiple executions of the same query
+ private Select _template = null;
+ private boolean _extent = false;
+ private int _cacheLevel = -1;
+
+ /**
+ * Return true if we know the select to have on criteria; to be an extent.
+ * Note that even if this method returns false, {@link #evaluate} may still
+ * return null if we haven't cached whether the query is an extent yet.
+ */
+ public boolean isExtent() {
+ return _extent;
+ }
+
+ /**
+ * Evaluate the expression, returning a SQL select with the proper
+ * conditions. Use {@link #select} to then select the data.
+ */
+ public Select evaluate(JDBCStore store, Select parent, String alias,
+ QueryExpressions exps, Object[] params, int level,
+ JDBCFetchState fetchState) {
+ // already know that this query is equivalent to an extent?
+ Select sel;
+ if (_extent) {
+ sel = store.getSQLFactory().newSelect();
+ sel.setAutoDistinct((exps.distinct & exps.DISTINCT_AUTO) != 0);
+ return sel;
+ }
+
+ // already cached some SQL? if we're changing our cache level, we
+ // have to abandon any already-cached data because a change means
+ // different joins
+ if (level != _cacheLevel)
+ _template = null;
+ _cacheLevel = level;
+
+ if (_template != null && level == CACHE_FULL) {
+ sel = (Select) _template.fullClone(1);
+ sel.setParent(parent, alias);
+ } else if (_template != null) {
+ sel = (Select) _template.whereClone(1);
+ sel.setParent(parent, alias);
+ } else {
+ // create a new select and initialize it with the joins needed for
+ // the criteria of this query
+ sel = newJoinsSelect(store, parent, alias, exps, params,
+ fetchState);
+ }
+
+ // if this select wasn't cloned from a full template,
+ // build up sql conditions
+ if (_template == null || level != CACHE_FULL) {
+ // create where clause; if there are no where conditions and
+ // no ordering or projections, we return null to signify that this
+ // query should be treated like an extent
+ Select inner = sel.getFromSelect();
+ SQLBuffer where = buildWhere((inner != null) ? inner : sel,
+ store, exps.filter, params, fetchState);
+ if (where == null && exps.projections.length == 0
+ && exps.ordering.length == 0
+ && (sel.getJoins() == null || sel.getJoins().isEmpty())) {
+ _extent = true;
+ sel = store.getSQLFactory().newSelect();
+ sel.setAutoDistinct((exps.distinct & exps.DISTINCT_AUTO) != 0);
+ return sel;
+ }
+
+ // if we're caching joins, do that now before we start setting sql.
+ // we can't cache subselects because they are also held in the
+ // where buffer
+ if (_template == null && level == CACHE_JOINS
+ && (inner == null || inner.getSubselects().isEmpty())
+ && sel.getSubselects().isEmpty()) {
+ _template = sel;
+ sel = (Select) sel.whereClone(1);
+ sel.setParent(parent, alias);
+ inner = sel.getFromSelect();
+ }
+
+ // now set sql criteria; it goes on the inner select if present
+ if (inner != null)
+ inner.where(where);
+ else
+ sel.where(where);
+
+ // apply grouping and having. this does not select the grouping
+ // columns, just builds the GROUP BY clauses. we don't build the
+ // ORDER BY clauses yet because if we decide to add this select
+ // to a union, the ORDER BY values get aliased differently
+ if (exps.having != null) {
+ Exp havingExp = (Exp) exps.having;
+ SQLBuffer buf = new SQLBuffer(store.getDBDictionary());
+ havingExp.appendTo(buf, sel, store, params, fetchState);
+ sel.having(buf);
+ }
+ for (int i = 0; i < exps.grouping.length; i++)
+ ((Val) exps.grouping[i]).groupBy(sel, store, params,
+ fetchState);
+
+ // if template is still null at this point, must be a full cache
+ if (_template == null && level == CACHE_FULL) {
+ _template = sel;
+ sel = (Select) _template.fullClone(1);
+ sel.setParent(parent, alias);
+ }
+ }
+ return sel;
+ }
+
+ /**
+ * Initialize the given select's joins.
+ */
+ private Select newJoinsSelect(JDBCStore store, Select parent,
+ String alias, QueryExpressions exps, Object[] params,
+ JDBCFetchState fetchState) {
+ Select sel = store.getSQLFactory().newSelect();
+ sel.setAutoDistinct((exps.distinct & exps.DISTINCT_AUTO) != 0);
+ JDBCFetchConfiguration fetch = (fetchState == null)
+ ?
+ (JDBCFetchConfiguration) store.getContext().getFetchConfiguration()
+ : fetchState.getJDBCFetchConfiguration();
+ sel.setJoinSyntax(fetch.getJoinSyntax());
+ sel.setParent(parent, alias);
+ initializeJoins(sel, store, exps, params);
+
+ if (!sel.getAutoDistinct()) {
+ if ((exps.distinct & exps.DISTINCT_TRUE) != 0)
+ sel.setDistinct(true);
+ else if ((exps.distinct & exps.DISTINCT_FALSE) != 0)
+ sel.setDistinct(false);
+ } else if (exps.projections.length > 0) {
+ if (!sel.isDistinct() && (exps.distinct & exps.DISTINCT_TRUE) != 0)
+ {
+ // if the select is not distinct but the query is, force
+ // the select to be distinct
+ sel.setDistinct(true);
+ } else if (sel.isDistinct()) {
+ // when aggregating data or making a non-distinct projection
+ // from a distinct select, we have to select from a tmp
+ // table formed by a distinct subselect in the from clause;
+ // this subselect selects the pks of the candidate (to
+ // get unique candidate values) and needed field values and
+ // applies the where conditions; the outer select applies
+ // ordering, grouping, etc
+ if (exps.aggregate || (exps.distinct & exps.DISTINCT_TRUE) == 0)
+ {
+ DBDictionary dict = store.getDBDictionary();
+ dict.assertSupport(dict.supportsSubselect,
+ "SupportsSubselect");
+
+ Select inner = sel;
+ sel = store.getSQLFactory().newSelect();
+ sel.setParent(parent, alias);
+ sel.setDistinct(exps.aggregate
+ && (exps.distinct & exps.DISTINCT_TRUE) != 0);
+ sel.setFromSelect(inner);
+ }
+ }
+ }
+ return sel;
+ }
+
+ /**
+ * Initialize the joins for all expressions. This only has to be done
+ * once for the template select, since each factory is only used for a
+ * single filter + projections + grouping + having + ordering combination.
+ * By initializing the joins once, we speed up subsequent executions
+ * because the relation traversal logic, etc is cached.
+ */
+ private void initializeJoins(Select sel, JDBCStore store,
+ QueryExpressions exps, Object[] params) {
+ Map contains = null;
+ if (((Exp) exps.filter).hasContainsExpression()
+ || (exps.having != null
+ && ((Exp) exps.having).hasContainsExpression()))
+ contains = new HashMap(7);
+
+ // initialize filter and having expressions
+ Exp filterExp = (Exp) exps.filter;
+ filterExp.initialize(sel, store, params, contains);
+ Exp havingExp = (Exp) exps.having;
+ if (havingExp != null)
+ havingExp.initialize(sel, store, params, contains);
+
+ // get the top-level joins and null the expression's joins
+ // at the same time so they aren't included in the where/having SQL
+ Joins filterJoins = filterExp.getJoins();
+ Joins havingJoins = (havingExp == null) ? null : havingExp.getJoins();
+ Joins joins = sel.and(filterJoins, havingJoins);
+
+ // initialize result values
+ Val resultVal;
+ for (int i = 0; i < exps.projections.length; i++) {
+ resultVal = (Val) exps.projections[i];
+ resultVal.initialize(sel, store, false);
+
+ // have to join through to related type for pc object projections;
+ // this ensures that we have all our joins cached
+ if (resultVal instanceof PCPath)
+ ((PCPath) resultVal).joinRelation();
+
+ joins = sel.and(joins, resultVal.getJoins());
+ }
+
+ // initialize grouping
+ Val groupVal;
+ for (int i = 0; i < exps.grouping.length; i++) {
+ groupVal = (Val) exps.grouping[i];
+ groupVal.initialize(sel, store, false);
+ joins = sel.and(joins, groupVal.getJoins());
+ }
+
+ // initialize ordering
+ Val orderVal;
+ for (int i = 0; i < exps.ordering.length; i++) {
+ orderVal = (Val) exps.ordering[i];
+ orderVal.initialize(sel, store, false);
+ joins = sel.and(joins, orderVal.getJoins());
+ }
+
+ sel.where(joins);
+ }
+
+ /**
+ * Create the where sql.
+ */
+ private SQLBuffer buildWhere(Select sel, JDBCStore store,
+ Expression filter, Object[] params, JDBCFetchState fetchState) {
+ // create where buffer
+ SQLBuffer where = new SQLBuffer(store.getDBDictionary());
+ where.append("(");
+ Exp filterExp = (Exp) filter;
+ filterExp.appendTo(where, sel, store, params, fetchState);
+
+ if (where.sqlEquals("(") || where.sqlEquals("(1 = 1"))
+ return null;
+ return where.append(")");
+ }
+
+ /**
+ * Select the data for this query.
+ */
+ public void select(JDBCStore store, ClassMapping mapping,
+ boolean subclasses, Select sel, QueryExpressions exps,
+ Object[] params, JDBCFetchState fetchState, int eager) {
+ Select inner = sel.getFromSelect();
+ Val val;
+ Joins joins = null;
+ if (sel.getSubselectPath() != null)
+ joins = sel.newJoins().setSubselect(sel.getSubselectPath());
+ JDBCFetchConfiguration fetch = fetchState.getJDBCFetchConfiguration();
+ // build ordering clauses before select so that any eager join
+ // ordering gets applied after query ordering
+ for (int i = 0; i < exps.ordering.length; i++)
+ ((Val) exps.ordering[i]).orderBy(sel, store, params,
+ exps.ascending[i], fetchState);
+
+ // if no result string set, select matching objects like normal
+ if (exps.projections.length == 0 && sel.getParent() == null) {
+ int subs = (subclasses) ? sel.SUBS_JOINABLE : sel.SUBS_NONE;
+ sel.selectIdentifier(mapping, subs, store, fetchState, eager);
+ } else if (exps.projections.length == 0) {
+ // subselect for objects; we really just need the primary key values
+ sel.select(mapping.getPrimaryKeyColumns(), joins);
+ } else {
+ // if we have an inner select, we need to select the candidate
+ // class' pk columns to guarantee unique instances
+ if (inner != null)
+ inner.select(mapping.getPrimaryKeyColumns(), joins);
+
+ // select each result value; no need to pass on the eager mode since
+ // under projections we always use EAGER_NONE
+ boolean pks = sel.getParent() != null;
+ for (int i = 0; i < exps.projections.length; i++) {
+ val = (Val) exps.projections[i];
+ if (inner != null)
+ val.selectColumns(inner, store, params, pks, fetchState);
+ val.select(sel, store, params, pks, fetchState);
+ }
+
+ // make sure grouping and having columns are selected since it
+ // is required by most DBs. put them last so they don't affect
+ // result processing
+ if (exps.having != null && inner != null)
+ ((Exp) exps.having).selectColumns(inner, store, params, true,
+ fetchState);
+ for (int i = 0; i < exps.grouping.length; i++) {
+ val = (Val) exps.grouping[i];
+ if (inner != null)
+ val.selectColumns(inner, store, params, true, fetchState);
+ val.select(sel, store, params, true, fetchState);
+ }
+ }
+
+ // select order data last so it doesn't affect result processing
+ for (int i = 0; i < exps.ordering.length; i++) {
+ val = (Val) exps.ordering[i];
+ if (inner != null)
+ val.selectColumns(inner, store, params, true, fetchState);
+ val.select(sel, store, params, true, fetchState);
+ }
+
+ // add conditions limiting the projections to the proper classes; if
+ // this isn't a projection then they will already be added
+ if (exps.projections.length > 0) {
+ Select indSel = (inner == null) ? sel : inner;
+ store.addClassConditions(indSel, mapping, subclasses, joins);
+ }
+ }
+}
Propchange: incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/SelectConstructor.java
------------------------------------------------------------------------------
svn:executable = *
Added: incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/Size.java
URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/Size.java?rev=423615&view=auto
==============================================================================
--- incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/Size.java (added)
+++ incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/Size.java Wed Jul 19 14:34:44 2006
@@ -0,0 +1,58 @@
+/*
+ * Copyright 2006 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.openjpa.jdbc.kernel.exps;
+
+import org.apache.openjpa.jdbc.kernel.JDBCFetchState;
+import org.apache.openjpa.jdbc.kernel.JDBCStore;
+import org.apache.openjpa.jdbc.sql.SQLBuffer;
+import org.apache.openjpa.jdbc.sql.Select;
+import org.apache.openjpa.util.InternalException;
+
+/**
+ * Size.
+ *
+ * @author Marc Prud'hommeaux
+ */
+class Size
+ extends UnaryOp
+ implements Val {
+
+ public Size(Val val) {
+ super(val);
+ }
+
+ public void initialize(Select sel, JDBCStore store, boolean nullTest) {
+ // initialize the value with a null test
+ getVal().initialize(sel, store, true);
+ }
+
+ public void appendTo(SQLBuffer sql, int index, Select sel,
+ JDBCStore store, Object[] params, JDBCFetchState fetchState) {
+ getVal().calculateValue(sel, store, params, null, fetchState);
+ getVal().appendSize(sql, sel, store, params, fetchState);
+ sel.append(sql, getVal().getJoins());
+ getVal().clearParameters();
+ }
+
+ protected Class getType(Class c) {
+ return long.class;
+ }
+
+ protected String getOperator() {
+ // since we override appendTo(), this method should never be called
+ throw new InternalException();
+ }
+}
Propchange: incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/Size.java
------------------------------------------------------------------------------
svn:executable = *
Added: incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/Sqrt.java
URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/Sqrt.java?rev=423615&view=auto
==============================================================================
--- incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/Sqrt.java (added)
+++ incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/Sqrt.java Wed Jul 19 14:34:44 2006
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2006 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.openjpa.jdbc.kernel.exps;
+
+/**
+ * Square root.
+ *
+ * @author Abe White
+ */
+class Sqrt
+ extends UnaryOp {
+
+ /**
+ * Constructor. Provide the value to operate on.
+ */
+ public Sqrt(Val val) {
+ super(val);
+ }
+
+ protected Class getType(Class c) {
+ return double.class;
+ }
+
+ protected String getOperator() {
+ return "SQRT";
+ }
+}
+
Propchange: incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/Sqrt.java
------------------------------------------------------------------------------
svn:executable = *
Added: incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/StartsWithExpression.java
URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/StartsWithExpression.java?rev=423615&view=auto
==============================================================================
--- incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/StartsWithExpression.java (added)
+++ incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/StartsWithExpression.java Wed Jul 19 14:34:44 2006
@@ -0,0 +1,266 @@
+/*
+ * Copyright 2006 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.openjpa.jdbc.kernel.exps;
+
+import java.util.Map;
+
+import org.apache.openjpa.jdbc.kernel.JDBCFetchState;
+import org.apache.openjpa.jdbc.kernel.JDBCStore;
+import org.apache.openjpa.jdbc.meta.ClassMapping;
+import org.apache.openjpa.jdbc.meta.FieldMapping;
+import org.apache.openjpa.jdbc.schema.Column;
+import org.apache.openjpa.jdbc.schema.Table;
+import org.apache.openjpa.jdbc.sql.DBDictionary;
+import org.apache.openjpa.jdbc.sql.Joins;
+import org.apache.openjpa.jdbc.sql.SQLBuffer;
+import org.apache.openjpa.jdbc.sql.Select;
+import serp.util.Numbers;
+
+/**
+ * Test if one string starts with another.
+ *
+ * @author Abe White
+ */
+class StartsWithExpression
+ implements Exp {
+
+ private final Val _val1;
+ private final Val _val2;
+ private Joins _joins = null;
+ private String _pre = null;
+ private String _post = null;
+
+ /**
+ * Constructor. Supply values.
+ */
+ public StartsWithExpression(Val val1, Val val2) {
+ _val1 = val1;
+ _val2 = val2;
+ }
+
+ public void initialize(Select sel, JDBCStore store,
+ Object[] params, Map contains) {
+ _val1.initialize(sel, store, false);
+ _val2.initialize(sel, store, false);
+ _joins = sel.and(_val1.getJoins(), _val2.getJoins());
+
+ DBDictionary dict = store.getDBDictionary();
+ String func = dict.stringLengthFunction;
+ if (func != null) {
+ int idx = func.indexOf("{0}");
+ _pre = func.substring(0, idx);
+ _post = func.substring(idx + 3);
+ }
+ }
+
+ public void appendTo(SQLBuffer buf, Select sel, JDBCStore store,
+ Object[] params, JDBCFetchState fetchState) {
+ _val1.calculateValue(sel, store, params, _val2, fetchState);
+ _val2.calculateValue(sel, store, params, _val1, fetchState);
+
+ if (_val1 instanceof Const && ((Const) _val1).getValue() == null)
+ buf.append("1 <> 1");
+ else if (_val2 instanceof Const) {
+ Object o = ((Const) _val2).getValue();
+ if (o == null)
+ buf.append("1 <> 1");
+ else {
+ Column col = null;
+ if (_val1 instanceof PCPath) {
+ Column[] cols = ((PCPath) _val1).getColumns();
+ if (cols.length == 1)
+ col = cols[0];
+ }
+
+ _val1.appendTo(buf, 0, sel, store, params, fetchState);
+ buf.append(" LIKE ");
+ buf.appendValue(o.toString() + "%", col);
+ }
+ } else {
+ // if we can't use LIKE, we have to take the substring of the
+ // first value and compare it to the second
+ DBDictionary dict = store.getDBDictionary();
+ dict.assertSupport(_pre != null, "StringLengthFunction");
+ dict.substring(buf,
+ new FilterValueImpl(_val1, sel, store, params, fetchState),
+ new ZeroFilterValue(sel),
+ new StringLengthFilterValue(sel, store, params, fetchState));
+ buf.append(" = ");
+ _val2.appendTo(buf, 0, sel, store, params, fetchState);
+ }
+
+ sel.append(buf, _joins);
+ _val1.clearParameters();
+ _val2.clearParameters();
+ }
+
+ public void selectColumns(Select sel, JDBCStore store,
+ Object[] params, boolean pks, JDBCFetchState fetchState) {
+ _val1.selectColumns(sel, store, params, true, fetchState);
+ _val2.selectColumns(sel, store, params, true, fetchState);
+ }
+
+ public Joins getJoins() {
+ return _joins;
+ }
+
+ public boolean hasContainsExpression() {
+ return false;
+ }
+
+ public boolean hasVariable(Variable var) {
+ return _val1.hasVariable(var) || _val2.hasVariable(var);
+ }
+
+ /**
+ * Evaluates to 0.
+ */
+ private class ZeroFilterValue
+ implements FilterValue {
+
+ private final Select _sel;
+
+ public ZeroFilterValue(Select sel) {
+ _sel = sel;
+ }
+
+ public Class getType() {
+ return int.class;
+ }
+
+ public int length() {
+ return 1;
+ }
+
+ public void appendTo(SQLBuffer buf) {
+ appendTo(buf, 0);
+ }
+
+ public void appendTo(SQLBuffer buf, int index) {
+ buf.appendValue(0);
+ }
+
+ public String getColumnAlias(Column col) {
+ return _sel.getColumnAlias(col, _joins);
+ }
+
+ public String getColumnAlias(String col, Table table) {
+ return _sel.getColumnAlias(col, table, _joins);
+ }
+
+ public Object toDataStoreValue(Object val) {
+ return val;
+ }
+
+ public boolean isConstant() {
+ return true;
+ }
+
+ public Object getValue() {
+ return Numbers.valueOf(0);
+ }
+
+ public Object getSQLValue() {
+ return Numbers.valueOf(0);
+ }
+
+ public boolean isPath() {
+ return false;
+ }
+
+ public ClassMapping getClassMapping() {
+ return null;
+ }
+
+ public FieldMapping getFieldMapping() {
+ return null;
+ }
+ }
+
+ /**
+ * Evaluates to the length of a given value.
+ */
+ private class StringLengthFilterValue
+ implements FilterValue {
+
+ private final Select _sel;
+ private final JDBCStore _store;
+ private final Object[] _params;
+ private final JDBCFetchState _fetchState;
+
+ public StringLengthFilterValue(Select sel, JDBCStore store,
+ Object[] params, JDBCFetchState fetchState) {
+ _sel = sel;
+ _store = store;
+ _params = params;
+ _fetchState = fetchState;
+ }
+
+ public Class getType() {
+ return int.class;
+ }
+
+ public int length() {
+ return 1;
+ }
+
+ public void appendTo(SQLBuffer buf) {
+ appendTo(buf, 0);
+ }
+
+ public void appendTo(SQLBuffer buf, int index) {
+ buf.append(_pre);
+ _val2.appendTo(buf, index, _sel, _store, _params, _fetchState);
+ buf.append(_post);
+ }
+
+ public String getColumnAlias(Column col) {
+ return _sel.getColumnAlias(col, _val2.getJoins());
+ }
+
+ public String getColumnAlias(String col, Table table) {
+ return _sel.getColumnAlias(col, table, _val2.getJoins());
+ }
+
+ public Object toDataStoreValue(Object val) {
+ return _val2.toDataStoreValue(val, _store);
+ }
+
+ public boolean isConstant() {
+ return false;
+ }
+
+ public Object getValue() {
+ return null;
+ }
+
+ public Object getSQLValue() {
+ return null;
+ }
+
+ public boolean isPath() {
+ return false;
+ }
+
+ public ClassMapping getClassMapping() {
+ return null;
+ }
+
+ public FieldMapping getFieldMapping() {
+ return null;
+ }
+ }
+}
Propchange: incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/StartsWithExpression.java
------------------------------------------------------------------------------
svn:executable = *
Added: incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/StringFunction.java
URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/StringFunction.java?rev=423615&view=auto
==============================================================================
--- incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/StringFunction.java (added)
+++ incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/StringFunction.java Wed Jul 19 14:34:44 2006
@@ -0,0 +1,138 @@
+/*
+ * Copyright 2006 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.openjpa.jdbc.kernel.exps;
+
+import java.sql.SQLException;
+
+import org.apache.openjpa.jdbc.kernel.JDBCFetchState;
+import org.apache.openjpa.jdbc.kernel.JDBCStore;
+import org.apache.openjpa.jdbc.meta.JavaSQLTypes;
+import org.apache.openjpa.jdbc.sql.Joins;
+import org.apache.openjpa.jdbc.sql.Result;
+import org.apache.openjpa.jdbc.sql.SQLBuffer;
+import org.apache.openjpa.jdbc.sql.Select;
+import org.apache.openjpa.kernel.Filters;
+import org.apache.openjpa.meta.ClassMetaData;
+
+/**
+ * A JDBC string function.
+ *
+ * @author Marc Prud'hommeaux
+ */
+abstract class StringFunction
+ extends AbstractVal
+ implements Val {
+
+ final Val _val;
+ ClassMetaData _meta = null;
+ String _pre = null;
+ String _post = null;
+
+ /**
+ * Constructor. Provide the string to operate on.
+ */
+ public StringFunction(Val val) {
+ _val = val;
+ }
+
+ public ClassMetaData getMetaData() {
+ return _meta;
+ }
+
+ public void setMetaData(ClassMetaData meta) {
+ _meta = meta;
+ }
+
+ public boolean isVariable() {
+ return false;
+ }
+
+ public Class getType() {
+ return String.class;
+ }
+
+ public void setImplicitType(Class type) {
+ }
+
+ public Joins getJoins() {
+ return _val.getJoins();
+ }
+
+ public Object toDataStoreValue(Object val, JDBCStore store) {
+ return val;
+ }
+
+ public void select(Select sel, JDBCStore store, Object[] params,
+ boolean pks, JDBCFetchState fetchState) {
+ sel.select(newSQLBuffer(sel, store, params, fetchState), this);
+ }
+
+ public void selectColumns(Select sel, JDBCStore store,
+ Object[] params, boolean pks, JDBCFetchState fetchState) {
+ _val.selectColumns(sel, store, params, true, fetchState);
+ }
+
+ public void groupBy(Select sel, JDBCStore store, Object[] params,
+ JDBCFetchState fetchState) {
+ sel.groupBy(newSQLBuffer(sel, store, params, fetchState), false);
+ }
+
+ public void orderBy(Select sel, JDBCStore store, Object[] params,
+ boolean asc, JDBCFetchState fetchState) {
+ sel.orderBy(newSQLBuffer(sel, store, params, fetchState), asc, false);
+ }
+
+ private SQLBuffer newSQLBuffer(Select sel, JDBCStore store,
+ Object[] params, JDBCFetchState fetchState) {
+ calculateValue(sel, store, params, null, fetchState);
+ SQLBuffer buf = new SQLBuffer(store.getDBDictionary());
+ appendTo(buf, 0, sel, store, params, fetchState);
+ clearParameters();
+ return buf;
+ }
+
+ public Object load(Result res, JDBCStore store,
+ JDBCFetchState fetchState)
+ throws SQLException {
+ return Filters.convert(res.getObject(this,
+ JavaSQLTypes.JDBC_DEFAULT, null), getType());
+ }
+
+ public boolean hasVariable(Variable var) {
+ return _val.hasVariable(var);
+ }
+
+ public void calculateValue(Select sel, JDBCStore store,
+ Object[] params, Val other, JDBCFetchState fetchState) {
+ _val.calculateValue(sel, store, params, null, fetchState);
+ }
+
+ public void clearParameters() {
+ _val.clearParameters();
+ }
+
+ public int length() {
+ return 1;
+ }
+
+ public void appendTo(SQLBuffer sql, int index, Select sel,
+ JDBCStore store, Object[] params, JDBCFetchState fetchState) {
+ sql.append(_pre);
+ _val.appendTo(sql, 0, sel, store, params, fetchState);
+ sql.append(_post);
+ }
+}
+
Propchange: incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/StringFunction.java
------------------------------------------------------------------------------
svn:executable = *
Added: incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/StringLength.java
URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/StringLength.java?rev=423615&view=auto
==============================================================================
--- incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/StringLength.java (added)
+++ incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/StringLength.java Wed Jul 19 14:34:44 2006
@@ -0,0 +1,61 @@
+/*
+ * Copyright 2006 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.openjpa.jdbc.kernel.exps;
+
+import org.apache.openjpa.jdbc.kernel.JDBCStore;
+import org.apache.openjpa.jdbc.sql.DBDictionary;
+import org.apache.openjpa.jdbc.sql.Select;
+
+/**
+ * Returns the number of characters in a string.
+ *
+ * @author Marc Prud'hommeaux
+ */
+class StringLength
+ extends StringFunction {
+
+ private Class _cast = null;
+
+ /**
+ * Constructor. Provide the string to operate on.
+ */
+ public StringLength(Val val) {
+ super(val);
+ }
+
+ public void initialize(Select sel, JDBCStore store, boolean nullTest) {
+ _val.initialize(sel, store, false);
+
+ DBDictionary dict = store.getConfiguration().getDBDictionaryInstance();
+ String func = dict.stringLengthFunction;
+ dict.assertSupport(func != null, "StringLengthFunction");
+
+ int idx = func.indexOf("{0}");
+ _pre = func.substring(0, idx);
+ _post = func.substring(idx + 3);
+ }
+
+ public Class getType() {
+ if (_cast != null)
+ return _cast;
+ return int.class;
+ }
+
+ public void setImplicitType(Class type) {
+ _cast = type;
+ }
+}
+
Propchange: incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/StringLength.java
------------------------------------------------------------------------------
svn:executable = *
Added: incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/SubQ.java
URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/SubQ.java?rev=423615&view=auto
==============================================================================
--- incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/SubQ.java (added)
+++ incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/SubQ.java Wed Jul 19 14:34:44 2006
@@ -0,0 +1,238 @@
+/*
+ * Copyright 2006 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.openjpa.jdbc.kernel.exps;
+
+import java.sql.SQLException;
+
+import org.apache.openjpa.jdbc.kernel.JDBCFetchConfiguration;
+import org.apache.openjpa.jdbc.kernel.JDBCFetchState;
+import org.apache.openjpa.jdbc.kernel.JDBCStore;
+import org.apache.openjpa.jdbc.meta.ClassMapping;
+import org.apache.openjpa.jdbc.meta.JavaSQLTypes;
+import org.apache.openjpa.jdbc.sql.Joins;
+import org.apache.openjpa.jdbc.sql.Result;
+import org.apache.openjpa.jdbc.sql.SQLBuffer;
+import org.apache.openjpa.jdbc.sql.Select;
+import org.apache.openjpa.kernel.Filters;
+import org.apache.openjpa.kernel.exps.QueryExpressions;
+import org.apache.openjpa.kernel.exps.Subquery;
+import org.apache.openjpa.meta.ClassMetaData;
+
+/**
+ * A subquery.
+ *
+ * @author Abe White
+ */
+class SubQ
+ implements Val, Subquery {
+
+ private final ClassMapping _candidate;
+ private final boolean _subs;
+ private final String _alias;
+ private final SelectConstructor _cons = new SelectConstructor();
+
+ private Class _type = null;
+ private ClassMetaData _meta = null;
+ private QueryExpressions _exps = null;
+ private long _startIdx = 0;
+ private long _endIdx = Long.MAX_VALUE;
+
+ /**
+ * Constructor. Supply candidate, whether subclasses are included in
+ * the query, and the query alias.
+ */
+ public SubQ(ClassMapping candidate, boolean subs, String alias) {
+ _candidate = candidate;
+ _subs = subs;
+ _alias = alias;
+ }
+
+ /**
+ * Return the subquery candidate type.
+ */
+ public ClassMapping getCandidate() {
+ return _candidate;
+ }
+
+ public Class getType() {
+ if (_exps != null) {
+ if (_exps.projections.length == 0)
+ return _candidate.getDescribedType();
+ if (_exps.projections.length == 1)
+ return _exps.projections[0].getType();
+ }
+ return _type;
+ }
+
+ public void setImplicitType(Class type) {
+ if (_exps != null && _exps.projections.length == 1)
+ _exps.projections[0].setImplicitType(type);
+ _type = type;
+ }
+
+ public boolean isVariable() {
+ return false;
+ }
+
+ public ClassMetaData getMetaData() {
+ return _meta;
+ }
+
+ public void setMetaData(ClassMetaData meta) {
+ _meta = meta;
+ }
+
+ public String getCandidateAlias() {
+ return _alias;
+ }
+
+ public void setQueryExpressions(QueryExpressions query, long startIdx,
+ long endIdx) {
+ _exps = query;
+ _startIdx = startIdx;
+ _endIdx = endIdx;
+ }
+
+ public void initialize(Select sel, JDBCStore store, boolean nullTest) {
+ }
+
+ public Joins getJoins() {
+ return null;
+ }
+
+ public Object toDataStoreValue(Object val, JDBCStore store) {
+ if (_exps.projections.length == 0)
+ return _candidate.toDataStoreValue(val,
+ _candidate.getPrimaryKeyColumns(), store);
+ if (_exps.projections.length == 1)
+ return ((Val) _exps.projections[0]).toDataStoreValue(val, store);
+ return val;
+ }
+
+ public void select(Select sel, JDBCStore store, Object[] params,
+ boolean pks, JDBCFetchState fetchState) {
+ selectColumns(sel, store, params, pks, fetchState);
+ }
+
+ public void selectColumns(Select sel, JDBCStore store,
+ Object[] params, boolean pks, JDBCFetchState fetchState) {
+ sel.select(newSQLBuffer(sel, store, params, fetchState), this);
+ }
+
+ public void groupBy(Select sel, JDBCStore store, Object[] params,
+ JDBCFetchState fetchState) {
+ sel.groupBy(newSQLBuffer(sel, store, params, fetchState), false);
+ }
+
+ public void orderBy(Select sel, JDBCStore store, Object[] params,
+ boolean asc, JDBCFetchState fetchState) {
+ sel.orderBy(newSQLBuffer(sel, store, params, fetchState), asc, false);
+ }
+
+ private SQLBuffer newSQLBuffer(Select sel, JDBCStore store,
+ Object[] params, JDBCFetchState fetchState) {
+ SQLBuffer buf = new SQLBuffer(store.getDBDictionary());
+ appendTo(buf, 0, sel, store, params, fetchState);
+ return buf;
+ }
+
+ public Object load(Result res, JDBCStore store,
+ JDBCFetchState fetchState)
+ throws SQLException {
+ return Filters.convert(res.getObject(this,
+ JavaSQLTypes.JDBC_DEFAULT, null), getType());
+ }
+
+ public boolean hasVariable(Variable var) {
+ for (int i = 0; i < _exps.projections.length; i++)
+ if (((Val) _exps.projections[i]).hasVariable(var))
+ return true;
+ if (_exps.filter != null)
+ if (((Exp) _exps.filter).hasVariable(var))
+ return true;
+ for (int i = 0; i < _exps.grouping.length; i++)
+ if (((Val) _exps.grouping[i]).hasVariable(var))
+ return true;
+ if (_exps.having != null)
+ if (((Exp) _exps.having).hasVariable(var))
+ return true;
+ for (int i = 0; i < _exps.ordering.length; i++)
+ if (((Val) _exps.ordering[i]).hasVariable(var))
+ return true;
+ return false;
+ }
+
+ public void calculateValue(Select sel, JDBCStore store,
+ Object[] params, Val other, JDBCFetchState fetchState) {
+ }
+
+ public void clearParameters() {
+ }
+
+ public int length() {
+ return 1;
+ }
+
+ public void appendTo(SQLBuffer sql, int index, Select sel,
+ JDBCStore store, Object[] params, JDBCFetchState fetchState) {
+ appendTo(sql, index, sel, store, params, fetchState, false);
+ }
+
+ private void appendTo(SQLBuffer sql, int index, Select sel,
+ JDBCStore store, Object[] params, JDBCFetchState fetchState,
+ boolean size) {
+ JDBCFetchConfiguration fetch = fetchState.getJDBCFetchConfiguration();
+ sel = _cons.evaluate(store, sel, _alias, _exps, params,
+ _cons.CACHE_NULL, fetchState);
+ _cons.select(store, _candidate, _subs, sel, _exps, params,
+ fetchState, fetch.EAGER_NONE);
+ sel.setRange(_startIdx, _endIdx);
+
+ if (size)
+ sql.appendCount(sel, fetch);
+ else
+ sql.append(sel, fetch);
+ }
+
+ public void appendIsEmpty(SQLBuffer sql, Select sel,
+ JDBCStore store, Object[] params, JDBCFetchState fetchState) {
+ sql.append("NOT EXISTS ");
+ appendTo(sql, 0, sel, store, params, fetchState);
+ }
+
+ public void appendIsNotEmpty(SQLBuffer sql, Select sel,
+ JDBCStore store, Object[] params, JDBCFetchState fetchState) {
+ sql.append("EXISTS ");
+ appendTo(sql, 0, sel, store, params, fetchState);
+ }
+
+ public void appendSize(SQLBuffer sql, Select sel, JDBCStore store,
+ Object[] params, JDBCFetchState fetchState) {
+ appendTo(sql, 0, sel, store, params, fetchState, true);
+ }
+
+ public void appendIsNull(SQLBuffer sql, Select sel,
+ JDBCStore store, Object[] params, JDBCFetchState fetchState) {
+ appendTo(sql, 0, sel, store, params, fetchState);
+ sql.append(" IS NULL");
+ }
+
+ public void appendIsNotNull(SQLBuffer sql, Select sel,
+ JDBCStore store, Object[] params, JDBCFetchState fetchState) {
+ appendTo(sql, 0, sel, store, params, fetchState);
+ sql.append(" IS NOT NULL");
+ }
+}
Propchange: incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/SubQ.java
------------------------------------------------------------------------------
svn:executable = *
Added: incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/Substring.java
URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/Substring.java?rev=423615&view=auto
==============================================================================
--- incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/Substring.java (added)
+++ incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/Substring.java Wed Jul 19 14:34:44 2006
@@ -0,0 +1,158 @@
+/*
+ * Copyright 2006 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.openjpa.jdbc.kernel.exps;
+
+import java.sql.SQLException;
+
+import org.apache.openjpa.jdbc.kernel.JDBCFetchState;
+import org.apache.openjpa.jdbc.kernel.JDBCStore;
+import org.apache.openjpa.jdbc.meta.JavaSQLTypes;
+import org.apache.openjpa.jdbc.sql.Joins;
+import org.apache.openjpa.jdbc.sql.Result;
+import org.apache.openjpa.jdbc.sql.SQLBuffer;
+import org.apache.openjpa.jdbc.sql.Select;
+import org.apache.openjpa.kernel.Filters;
+import org.apache.openjpa.meta.ClassMetaData;
+
+/**
+ * Take a substring of a string.
+ *
+ * @author Abe White
+ */
+class Substring
+ extends AbstractVal
+ implements Val {
+
+ private final Val _val1;
+ private final Val _val2;
+ private Joins _joins = null;
+ private ClassMetaData _meta = null;
+
+ /**
+ * Constructor. Provide the strings to operate on.
+ */
+ public Substring(Val val1, Val val2) {
+ _val1 = val1;
+ _val2 = val2;
+ }
+
+ public ClassMetaData getMetaData() {
+ return _meta;
+ }
+
+ public void setMetaData(ClassMetaData meta) {
+ _meta = meta;
+ }
+
+ public boolean isVariable() {
+ return false;
+ }
+
+ public Class getType() {
+ return String.class;
+ }
+
+ public void setImplicitType(Class type) {
+ }
+
+ public void initialize(Select sel, JDBCStore store, boolean nullTest) {
+ _val1.initialize(sel, store, false);
+ _val2.initialize(sel, store, false);
+ _joins = sel.and(_val1.getJoins(), _val2.getJoins());
+ }
+
+ public Joins getJoins() {
+ return _joins;
+ }
+
+ public Object toDataStoreValue(Object val, JDBCStore store) {
+ return val;
+ }
+
+ public void select(Select sel, JDBCStore store, Object[] params,
+ boolean pks, JDBCFetchState fetchState) {
+ sel.select(newSQLBuffer(sel, store, params, fetchState), this);
+ }
+
+ public void selectColumns(Select sel, JDBCStore store,
+ Object[] params, boolean pks, JDBCFetchState fetchState) {
+ _val1.selectColumns(sel, store, params, true, fetchState);
+ _val2.selectColumns(sel, store, params, true, fetchState);
+ }
+
+ public void groupBy(Select sel, JDBCStore store, Object[] params,
+ JDBCFetchState fetchState) {
+ sel.groupBy(newSQLBuffer(sel, store, params, fetchState), false);
+ }
+
+ public void orderBy(Select sel, JDBCStore store, Object[] params,
+ boolean asc, JDBCFetchState fetchState) {
+ sel.orderBy(newSQLBuffer(sel, store, params, fetchState), asc, false);
+ }
+
+ private SQLBuffer newSQLBuffer(Select sel, JDBCStore store,
+ Object[] params, JDBCFetchState fetchState) {
+ calculateValue(sel, store, params, null, fetchState);
+ SQLBuffer buf = new SQLBuffer(store.getDBDictionary());
+ appendTo(buf, 0, sel, store, params, fetchState);
+ clearParameters();
+ return buf;
+ }
+
+ public Object load(Result res, JDBCStore store,
+ JDBCFetchState fetchState)
+ throws SQLException {
+ return Filters.convert(res.getObject(this,
+ JavaSQLTypes.JDBC_DEFAULT, null), getType());
+ }
+
+ public boolean hasVariable(Variable var) {
+ return _val1.hasVariable(var) || _val2.hasVariable(var);
+ }
+
+ public void calculateValue(Select sel, JDBCStore store,
+ Object[] params, Val other, JDBCFetchState fetchState) {
+ _val1.calculateValue(sel, store, params, null, fetchState);
+ _val2.calculateValue(sel, store, params, null, fetchState);
+ }
+
+ public void clearParameters() {
+ _val1.clearParameters();
+ _val2.clearParameters();
+ }
+
+ public int length() {
+ return 1;
+ }
+
+ public void appendTo(SQLBuffer sql, int index, Select sel,
+ JDBCStore store, Object[] params, JDBCFetchState fetchState) {
+ FilterValue str = new FilterValueImpl(_val1, sel, store, params,
+ fetchState);
+ FilterValue start;
+ FilterValue end = null;
+ if (_val2 instanceof Args) {
+ Val[] args = ((Args) _val2).getVals();
+ start =
+ new FilterValueImpl(args[0], sel, store, params, fetchState);
+ end = new FilterValueImpl(args[1], sel, store, params, fetchState);
+ } else
+ start = new FilterValueImpl(_val2, sel, store, params, fetchState);
+
+ store.getDBDictionary().substring(sql, str, start, end);
+ }
+}
+
Propchange: incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/Substring.java
------------------------------------------------------------------------------
svn:executable = *
Added: incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/Sum.java
URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/Sum.java?rev=423615&view=auto
==============================================================================
--- incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/Sum.java (added)
+++ incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/Sum.java Wed Jul 19 14:34:44 2006
@@ -0,0 +1,51 @@
+/*
+ * Copyright 2006 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.openjpa.jdbc.kernel.exps;
+
+import org.apache.openjpa.kernel.Filters;
+
+/**
+ * Sum.
+ *
+ * @author Abe White
+ */
+class Sum
+ extends UnaryOp {
+
+ /**
+ * Constructor. Provide the value to operate on.
+ */
+ public Sum(Val val) {
+ super(val);
+ }
+
+ protected Class getType(Class c) {
+ Class wrap = Filters.wrap(c);
+ if (wrap == Integer.class
+ || wrap == Short.class
+ || wrap == Byte.class)
+ return long.class;
+ return c;
+ }
+
+ protected String getOperator() {
+ return "SUM";
+ }
+
+ protected boolean isAggregate() {
+ return true;
+ }
+}
Propchange: incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/Sum.java
------------------------------------------------------------------------------
svn:executable = *