001: package com.quadcap.sql;
002:
003: /* Copyright 1999 - 2003 Quadcap Software. All rights reserved.
004: *
005: * This software is distributed under the Quadcap Free Software License.
006: * This software may be used or modified for any purpose, personal or
007: * commercial. Open Source redistributions are permitted. Commercial
008: * redistribution of larger works derived from, or works which bundle
009: * this software requires a "Commercial Redistribution License"; see
010: * http://www.quadcap.com/purchase.
011: *
012: * Redistributions qualify as "Open Source" under one of the following terms:
013: *
014: * Redistributions are made at no charge beyond the reasonable cost of
015: * materials and delivery.
016: *
017: * Redistributions are accompanied by a copy of the Source Code or by an
018: * irrevocable offer to provide a copy of the Source Code for up to three
019: * years at the cost of materials and delivery. Such redistributions
020: * must allow further use, modification, and redistribution of the Source
021: * Code under substantially the same terms as this license.
022: *
023: * Redistributions of source code must retain the copyright notices as they
024: * appear in each source code file, these license terms, and the
025: * disclaimer/limitation of liability set forth as paragraph 6 below.
026: *
027: * Redistributions in binary form must reproduce this Copyright Notice,
028: * these license terms, and the disclaimer/limitation of liability set
029: * forth as paragraph 6 below, in the documentation and/or other materials
030: * provided with the distribution.
031: *
032: * The Software is provided on an "AS IS" basis. No warranty is
033: * provided that the Software is free of defects, or fit for a
034: * particular purpose.
035: *
036: * Limitation of Liability. Quadcap Software shall not be liable
037: * for any damages suffered by the Licensee or any third party resulting
038: * from use of the Software.
039: */
040:
041: import java.io.Externalizable;
042: import java.io.IOException;
043: import java.io.ObjectInput;
044: import java.io.ObjectOutput;
045:
046: import java.sql.SQLException;
047:
048: import com.quadcap.sql.index.BCursor;
049: import com.quadcap.sql.index.Btree;
050:
051: import com.quadcap.sql.types.Op;
052: import com.quadcap.sql.types.Type;
053: import com.quadcap.sql.types.TypeBoolean;
054: import com.quadcap.sql.types.Value;
055: import com.quadcap.sql.types.ValueBoolean;
056:
057: import com.quadcap.util.Debug;
058:
059: /**
060: * Expression implementing unary ops.
061: *
062: * @author Stan Bailes
063: */
064: public class UnaryExpression extends Expression implements
065: Externalizable {
066: Expression e = null;
067: int op = -1;
068: boolean not = false;
069: Value value = null;
070:
071: public UnaryExpression() {
072: }
073:
074: public UnaryExpression(int op, Expression e) {
075: this .op = op;
076: this .e = e;
077: }
078:
079: public void invert() {
080: not = !not;
081: }
082:
083: public int rank() {
084: return 0;
085: }
086:
087: public Value uniqueValue(Session session, Cursor cursor)
088: throws SQLException, IOException {
089: Cursor c = e.getCursor(session, cursor);
090: try {
091: Btree index = session.makeTempTree();
092: try {
093: BCursor bc = index.getCursor(true);
094: try {
095: while (c.next()) {
096: Row row = c.getRow();
097: byte[] key = Key.makeKey(null, row, null, 0,
098: false);
099: if (bc.seek(key)) {
100: return ValueBoolean.trueBoolean;
101: } else {
102: bc.insert(key, key.length, key, 0, 1);
103: }
104: }
105: return ValueBoolean.falseBoolean;
106: } finally {
107: bc.release();
108: }
109: } finally {
110: try {
111: index.free();
112: } finally {
113: session.getDatabase().releaseTempFile();
114: }
115: }
116:
117: } finally {
118: c.close();
119: }
120: }
121:
122: public Value existsValue(Session session, Cursor cursor)
123: throws SQLException {
124: Cursor c = e.getCursor(session, cursor);
125: try {
126: Value ret = new ValueBoolean(c.next());
127: if (not)
128: ret = ret.unop(Op.NOT);
129: //Debug.println("c = " + c.getClass().getName() + ":" + c);
130: //Debug.println("[" + toString() + "].existsValue(" + cursor.getRow() + ") = " + ret);
131: return ret;
132: } finally {
133: c.close();
134: }
135: }
136:
137: public Type getType(Session session, Cursor cursor)
138: throws SQLException {
139: switch (op) {
140: case Op.EXISTS:
141: case Op.UNIQUE:
142: return TypeBoolean.typeBoolean;
143: default:
144: return e.getType(session, cursor);
145: }
146: }
147:
148: public Value getValue(Session session, Cursor cursor)
149: throws SQLException {
150: switch (op) {
151: case Op.EXISTS:
152: return existsValue(session, cursor);
153: case Op.UNIQUE:
154: try {
155: return uniqueValue(session, cursor);
156: } catch (IOException ex) {
157: throw DbException.wrapThrowable(ex);
158: }
159: default:
160: Value v = e.getValue(session, cursor);
161: value = v.unop(op);
162: if (not) {
163: value = value.unop(Op.NOT);
164: }
165: return value;
166: }
167: }
168:
169: public void visitSubExpressions(ExpressionVisitor ev) {
170: ev.visit(e);
171: }
172:
173: public String toString() {
174: String n = not ? "NOT " : "";
175: return n + Op.toString(op) + " " + e.toString();
176: }
177:
178: public void readExternal(ObjectInput in) throws IOException,
179: ClassNotFoundException {
180: e = (Expression) in.readObject();
181: op = in.readInt();
182: not = in.read() == 1;
183: value = (Value) in.readObject();
184: }
185:
186: public void writeExternal(ObjectOutput out) throws IOException {
187: out.writeObject(e);
188: out.writeInt(op);
189: out.write(not ? 1 : 0);
190: out.writeObject(value);
191: }
192: }
|