1 24 25 package com.mckoi.database.interpret; 26 27 import com.mckoi.database.Variable; 28 import com.mckoi.database.TableName; 29 import com.mckoi.database.Expression; 30 import com.mckoi.database.DatabaseSystem; 31 import com.mckoi.database.DatabaseException; 32 import com.mckoi.database.StatementException; 33 import com.mckoi.database.ExpressionPreparer; 34 import com.mckoi.database.CorrelatedVariable; 35 import com.mckoi.database.DatabaseConnection; 36 import java.util.ArrayList ; 37 38 47 48 class TableExpressionFromSet { 49 50 54 private ArrayList table_resources; 55 56 61 private ArrayList function_resources; 62 63 69 private ArrayList exposed_variables; 70 71 74 private boolean case_insensitive = false; 75 76 82 private TableExpressionFromSet parent; 83 84 85 86 87 88 91 public TableExpressionFromSet(DatabaseConnection connection) { 92 table_resources = new ArrayList (); 93 function_resources = new ArrayList (); 94 exposed_variables = new ArrayList (); 95 this.case_insensitive = connection.isInCaseInsensitiveMode(); 97 } 98 99 102 public void setParent(TableExpressionFromSet parent) { 103 this.parent = parent; 104 } 105 106 109 public TableExpressionFromSet getParent() { 110 return parent; 111 } 112 113 116 public void setCaseInsensitive(boolean status) { 117 case_insensitive = status; 118 } 119 120 boolean stringCompare(String str1, String str2) { 121 if (!case_insensitive) { 122 return str1.equals(str2); 123 } 124 return str1.equalsIgnoreCase(str2); 125 } 126 127 130 public void addTable(FromTableInterface table_resource) { 131 table_resources.add(table_resource); 132 } 133 134 139 public void addFunctionRef(String name, Expression expression) { 140 function_resources.add(name); 142 function_resources.add(expression); 143 } 144 145 151 public void exposeVariable(Variable v) { 152 exposed_variables.add(v); 155 } 156 157 160 public void exposeAllColumnsFromSource(FromTableInterface table) { 161 Variable[] v = table.allColumns(); 162 for (int p = 0; p < v.length; ++p) { 163 exposeVariable(v[p]); 164 } 165 } 166 167 170 public void exposeAllColumns() { 171 for (int i = 0; i < setCount(); ++i) { 172 exposeAllColumnsFromSource(getTable(i)); 173 } 174 } 175 176 179 public void exposeAllColumnsFromSource(TableName tn) { 180 FromTableInterface table_interface = 181 findTable(tn.getSchema(), tn.getName()); 182 if (table_interface == null) { 183 throw new StatementException("Table name found: " + tn); 184 } 185 exposeAllColumnsFromSource(table_interface); 186 } 187 188 193 public Variable[] generateResolvedVariableList() { 194 int sz = exposed_variables.size(); 195 Variable[] list = new Variable[sz]; 196 for (int i = 0; i < sz; ++i) { 197 list[i] = new Variable((Variable) exposed_variables.get(i)); 198 } 199 return list; 200 } 201 202 207 FromTableInterface findTable(String schema, String name) { 208 for (int p = 0; p < setCount(); ++p) { 209 FromTableInterface table = getTable(p); 210 if (table.matchesReference(null, schema, name)) { 211 return table; 212 } 213 } 214 return null; 215 } 216 217 220 int setCount() { 221 return table_resources.size(); 222 } 223 224 228 FromTableInterface getTable(int i) { 229 return (FromTableInterface) table_resources.get(i); 230 } 231 232 233 241 Expression dereferenceAssignment(Variable v) { 242 TableName tname = v.getTableName(); 243 String var_name = v.getName(); 244 if (tname != null) { 247 return null; 248 } 249 250 Expression last_found = null; 252 int matches_found = 0; 253 for (int i = 0; i < function_resources.size(); i += 2) { 254 String fun_name = (String ) function_resources.get(i); 255 if (stringCompare(fun_name, var_name)) { 256 if (matches_found > 0) { 257 throw new StatementException("Ambiguous reference '" + v + "'"); 258 } 259 last_found = (Expression) function_resources.get(i + 1); 260 ++matches_found; 261 } 262 } 263 264 return last_found; 265 } 266 267 274 private Variable resolveAssignmentReference(Variable v) { 275 TableName tname = v.getTableName(); 276 String var_name = v.getName(); 277 if (tname != null) { 280 return null; 281 } 282 283 Variable last_found = null; 285 int matches_found = 0; 286 for (int i = 0; i < function_resources.size(); i += 2) { 287 String fun_name = (String ) function_resources.get(i); 288 if (stringCompare(fun_name, var_name)) { 289 if (matches_found > 0) { 290 throw new StatementException("Ambiguous reference '" + v + "'"); 291 } 292 last_found = new Variable(fun_name); 293 ++matches_found; 294 } 295 } 296 297 return last_found; 298 } 299 300 301 309 Variable resolveTableColumnReference(Variable v) { 310 TableName tname = v.getTableName(); 311 String sch_name = null; 312 String tab_name = null; 313 String col_name = v.getName(); 314 if (tname != null) { 315 sch_name = tname.getSchema(); 316 tab_name = tname.getName(); 317 } 318 319 Variable matched_var = null; 321 322 for (int i = 0; i < table_resources.size(); ++i) { 323 FromTableInterface table = (FromTableInterface) table_resources.get(i); 324 int rcc = table.resolveColumnCount(null, sch_name, tab_name, col_name); 325 if (rcc == 0) { 326 } 328 else if (rcc == 1 && matched_var == null) { 329 matched_var = 331 table.resolveColumn(null, sch_name, tab_name, col_name); 332 } 333 else { System.out.println(matched_var); 335 System.out.println(rcc); 336 throw new StatementException("Ambiguous reference '" + v + "'"); 337 } 338 } 339 340 return matched_var; 341 } 342 343 356 Variable resolveReference(Variable v) { 357 ArrayList list = new ArrayList (); 359 360 373 Variable function_var = resolveAssignmentReference(v); 374 if (function_var != null) { 375 list.add(function_var); 376 } 377 378 Variable tc_var = resolveTableColumnReference(v); 379 if (tc_var != null) { 380 list.add(tc_var); 381 } 382 383 406 int list_size = list.size(); 408 if (list_size == 0) { 409 return null; 410 } 411 else if (list_size == 1) { 412 return (Variable) list.get(0); 413 } 414 else { 415 throw new StatementException("Ambiguous reference '" + v + "'"); 420 } 425 426 } 427 428 438 CorrelatedVariable globalResolveReference(int level, Variable v) { 439 Variable nv = resolveReference(v); 440 if (nv == null && getParent() != null) { 441 return getParent().globalResolveReference(level + 1, v); 443 } 444 else if (nv != null) { 445 return new CorrelatedVariable(nv, level); 446 } 447 return null; 448 } 449 450 457 Object qualifyVariable(Variable v_in) { 458 Variable v = resolveReference(v_in); 459 if (v == null) { 460 if (getParent() != null) { 462 CorrelatedVariable cv = getParent().globalResolveReference(1, v_in); 463 if (cv == null) { 464 throw new StatementException("Reference '" + 465 v_in + "' not found."); 466 } 467 return cv; 468 } 469 if (v == null) { 470 throw new StatementException("Reference '" + 471 v_in + "' not found."); 472 } 473 } 474 return v; 475 } 476 477 481 ExpressionPreparer expressionQualifier() { 482 return new ExpressionPreparer() { 483 public boolean canPrepare(Object element) { 484 return element instanceof Variable; 485 } 486 public Object prepare(Object element) throws DatabaseException { 487 return qualifyVariable((Variable) element); 488 } 489 }; 490 } 491 492 } 493 | Popular Tags |