Quadcap Embeddable Database

com/quadcap/sql/Analyze.java

Go to the documentation of this file.
00001 package com.quadcap.sql; 00002 00003 /* Copyright 1999 - 2003 Quadcap Software. All rights reserved. 00004 * 00005 * This software is distributed under the Quadcap Free Software License. 00006 * This software may be used or modified for any purpose, personal or 00007 * commercial. Open Source redistributions are permitted. Commercial 00008 * redistribution of larger works derived from, or works which bundle 00009 * this software requires a "Commercial Redistribution License"; see 00010 * http://www.quadcap.com/purchase. 00011 * 00012 * Redistributions qualify as "Open Source" under one of the following terms: 00013 * 00014 * Redistributions are made at no charge beyond the reasonable cost of 00015 * materials and delivery. 00016 * 00017 * Redistributions are accompanied by a copy of the Source Code or by an 00018 * irrevocable offer to provide a copy of the Source Code for up to three 00019 * years at the cost of materials and delivery. Such redistributions 00020 * must allow further use, modification, and redistribution of the Source 00021 * Code under substantially the same terms as this license. 00022 * 00023 * Redistributions of source code must retain the copyright notices as they 00024 * appear in each source code file, these license terms, and the 00025 * disclaimer/limitation of liability set forth as paragraph 6 below. 00026 * 00027 * Redistributions in binary form must reproduce this Copyright Notice, 00028 * these license terms, and the disclaimer/limitation of liability set 00029 * forth as paragraph 6 below, in the documentation and/or other materials 00030 * provided with the distribution. 00031 * 00032 * The Software is provided on an "AS IS" basis. No warranty is 00033 * provided that the Software is free of defects, or fit for a 00034 * particular purpose. 00035 * 00036 * Limitation of Liability. Quadcap Software shall not be liable 00037 * for any damages suffered by the Licensee or any third party resulting 00038 * from use of the Software. 00039 */ 00040 00041 import java.util.Vector; 00042 00043 import java.sql.SQLException; 00044 00045 import com.quadcap.sql.types.Op; 00046 00047 import com.quadcap.util.Debug; 00048 00049 /** 00050 * Join planner. 00051 * 00052 * @author Stan Bailes 00053 */ 00054 public class Analyze { 00055 Session session; 00056 Expression expr; 00057 BinaryExpression b = null; 00058 NameExpression n = null; 00059 ValueExpression v = null; 00060 //#ifdef DEBUG 00061 String prefix = ""; 00062 //#endif 00063 00064 public Analyze(Session session, Expression expr) { 00065 this.session = session; 00066 this.expr = expr; 00067 if (expr instanceof BinaryExpression) b = (BinaryExpression)expr; 00068 if (expr instanceof NameExpression) n = (NameExpression)expr; 00069 if (expr instanceof ValueExpression) v = (ValueExpression)expr; 00070 } 00071 00072 public void getConjunctives(Vector v) { 00073 if (b != null) { 00074 if (b.not) { 00075 // XXX could get fancy and try to DeMorgan'ize it. 00076 v.addElement(expr); 00077 } else { 00078 if (b.op == Op.AND) { 00079 analyze(b.e).getConjunctives(v); 00080 analyze(b.f).getConjunctives(v); 00081 } else { 00082 v.addElement(expr); 00083 } 00084 } 00085 } else { 00086 v.addElement(expr); 00087 } 00088 } 00089 00090 public boolean isConstant() { 00091 return expr instanceof ValueExpression; 00092 } 00093 00094 public boolean isName() { 00095 return n != null; 00096 } 00097 00098 public boolean refersTo(Tuple table) throws SQLException { 00099 boolean ret = false; 00100 if (n != null) { 00101 if (table.getColumn(n.name) != null) ret = true; 00102 } 00103 return ret; 00104 } 00105 00106 public Analyze analyze(Expression e) { 00107 Analyze z = new Analyze(session, e); 00108 //#ifdef DEBUG 00109 z.prefix = prefix + " "; 00110 //#endif 00111 return z; 00112 } 00113 00114 public boolean isConstantCompareToTable(Tuple table) throws SQLException { 00115 boolean ret = false; 00116 if (b != null) { 00117 Analyze be = analyze(b.e); 00118 Analyze bf = analyze(b.f); 00119 if (be.isConstant()) { 00120 if (bf.refersTo(table)) { 00121 ret = true; 00122 } 00123 } else if (bf.isConstant()) { 00124 if (be.refersTo(table)) { 00125 ret = true; 00126 } 00127 } 00128 } 00129 //Debug.println("Analyze[" + expr + "].isConstantCompareToTable(" + 00130 // table.getName() + ") = " + ret); 00131 return ret; 00132 } 00133 00134 public boolean isTermOrConstant(Tuple table) throws SQLException { 00135 boolean ret = false; 00136 if (n != null) { 00137 ret = refersTo(table); 00138 } else if (b != null) { 00139 Analyze be = analyze(b.e); 00140 Analyze bf = analyze(b.f); 00141 ret = be.isTermOrConstant(table) && bf.isTermOrConstant(table); 00142 } else if (v != null) { 00143 ret = true; 00144 } 00145 return ret; 00146 } 00147 00148 public int[][] getJoinColumns(Cursor ca, Cursor cb) throws SQLException { 00149 Vector vec = new Vector(); 00150 Vector aCols = new Vector(); 00151 Vector bCols = new Vector(); 00152 int cnt = 0; 00153 int[][] ret = null; 00154 getConjunctives(vec); 00155 for (int i = 0; i < vec.size(); i++) { 00156 Expression ei = (Expression)vec.elementAt(i); 00157 if (analyze(ei).isJoinColumn(ca, aCols, cb, bCols)) { 00158 cnt++; 00159 } 00160 } 00161 if (cnt > 0) { 00162 ret = new int[2][cnt]; 00163 for (int i = 0; i < cnt; i++) { 00164 ret[0][i] = ((Column)aCols.elementAt(i)).getColumn(); 00165 ret[1][i] = ((Column)bCols.elementAt(i)).getColumn(); 00166 } 00167 } 00168 return ret; 00169 } 00170 00171 boolean isJoinColumn(Cursor ca, Vector aCols, Cursor cb, Vector bCols) 00172 throws SQLException 00173 { 00174 if (b == null) return false; 00175 if (b.op != Op.EQ) return false; 00176 if (!(b.e instanceof NameExpression)) return false; 00177 String ename = ((NameExpression)b.e).name; 00178 if (!(b.f instanceof NameExpression)) return false; 00179 String fname = ((NameExpression)b.f).name; 00180 Column cea = ca.getColumn(ename); 00181 if (cea != null) { 00182 Column cfb = cb.getColumn(fname); 00183 if (cfb != null) { 00184 aCols.addElement(cea); 00185 bCols.addElement(cfb); 00186 return true; 00187 } 00188 } 00189 Column ceb = cb.getColumn(ename); 00190 if (ceb != null) { 00191 Column cfa = ca.getColumn(fname); 00192 if (cfa != null) { 00193 aCols.addElement(cfa); 00194 bCols.addElement(ceb); 00195 return true; 00196 } 00197 } 00198 return false; 00199 } 00200 00201 public Expression factorTable(Tuple table) throws SQLException { 00202 Expression ret = null; 00203 if (table != null) { 00204 Vector vec = new Vector(); 00205 getConjunctives(vec); 00206 for (int i = 0; i < vec.size(); i++) { 00207 Expression ei = (Expression)vec.elementAt(i); 00208 if (analyze(ei).isTermOrConstant(table)) { 00209 if (ret == null) { 00210 ret = ei; 00211 } else { 00212 ret = new BinaryExpression(Op.AND, ret, ei); 00213 } 00214 } 00215 } 00216 } 00217 // Debug.println("Analyze[" + expr + "].factorTable(" + 00218 // (table == null ? "null" : table.getName()) + ") => " + 00219 // ret); 00220 return ret; 00221 00222 } 00223 00224 public boolean isJoinExpression(Tuple c) throws SQLException { 00225 boolean ret = false; 00226 if (isConstant()) { 00227 ret = true; 00228 } else if (n != null) { 00229 if (c.getColumn(n.name) != null) ret = true; 00230 } else if (b != null) { 00231 if (analyze(b.e).isJoinExpression(c) && 00232 analyze(b.f).isJoinExpression(c)) ret = true; 00233 } 00234 return ret; 00235 } 00236 00237 public Expression factorJoinExpression(Tuple c) throws SQLException { 00238 Expression ret = null; 00239 Vector vec = new Vector(); 00240 getConjunctives(vec); 00241 for (int i = 0; i < vec.size(); i++) { 00242 Expression ei = (Expression)vec.elementAt(i); 00243 if (analyze(ei).isJoinExpression(c)) { 00244 if (ret == null) { 00245 ret = ei; 00246 } else { 00247 ret = new BinaryExpression(Op.AND, ret, ei); 00248 } 00249 } 00250 } 00251 return ret; 00252 } 00253 00254 //#ifdef DEBUG 00255 public String toString() { 00256 return prefix + "Analyze[" + expr + "]"; 00257 } 00258 //#endif 00259 }