1 21 package oracle.toplink.essentials.internal.parsing; 23 24 import java.util.ArrayList ; 25 import java.util.Iterator ; 26 import java.util.List ; 27 28 import oracle.toplink.essentials.queryframework.*; 29 import oracle.toplink.essentials.expressions.Expression; 30 import oracle.toplink.essentials.expressions.ExpressionBuilder; 31 import oracle.toplink.essentials.descriptors.ClassDescriptor; 32 33 59 public class SelectNode extends QueryNode { 60 61 private List selectExpressions = new ArrayList (); 62 private boolean distinct =false; 63 64 public SelectNode() { 65 } 66 67 71 private void addSelectExpression(Object theNode) { 72 selectExpressions.add(theNode); 73 } 74 75 76 public List getSelectExpressions() { 77 return selectExpressions; 78 } 79 80 81 public void setSelectExpressions(List exprs) { 82 selectExpressions = exprs; 83 } 84 85 86 public boolean usesDistinct() { 87 return distinct; 88 } 89 90 91 public void setDistinct(boolean distinct) { 92 this.distinct = distinct; 93 } 94 95 99 public void applyToQuery(DatabaseQuery theQuery, GenerationContext context) { 100 ObjectLevelReadQuery readQuery = (ObjectLevelReadQuery)theQuery; 101 if (selectExpressions.isEmpty()) { 102 return; 103 } 104 105 if (!(isSingleSelectExpression() && getFirstSelectExpressionNode().isCountNode())) { 108 if (usesDistinct()) { 110 getParseTree().setDistinctState(ObjectLevelReadQuery.USE_DISTINCT); 111 readQuery.setDistinctState(ObjectLevelReadQuery.USE_DISTINCT); 112 } 113 } 114 115 if (readQuery instanceof ReportQuery) { 116 ReportQuery reportQuery = (ReportQuery)readQuery; 117 reportQuery.returnWithoutReportQueryResult(); 118 if (isSingleSelectExpression() && 119 !getFirstSelectExpressionNode().isConstructorNode()) { 120 reportQuery.returnSingleAttribute(); 121 } 122 } 123 SelectGenerationContext selectContext = (SelectGenerationContext)context; 124 for (Iterator i = selectExpressions.iterator(); i.hasNext();) { 125 Node node = (Node)i.next(); 126 if (selectingRelationshipField(node, context)) { 127 selectContext.useOuterJoins(); 128 } 129 node.applyToQuery(readQuery, context); 130 selectContext.dontUseOuterJoins(); 131 } 132 133 if (this.hasOneToOneSelected(context)) { 136 readQuery.setProperty("return null if primary key is null", Boolean.TRUE); 137 } else { 138 readQuery.removeProperty("return null if primary key is null"); 139 } 140 141 } 142 143 146 public boolean hasOneToOneSelected(GenerationContext context) { 147 for (Iterator i = selectExpressions.iterator(); i.hasNext();) { 150 Node node = (Node)i.next(); 151 if (hasOneToOneSelected(node, context)) { 152 return true; 153 } 154 } 155 return false; 156 } 157 158 167 private boolean hasOneToOneSelected(Node node, GenerationContext context) { 168 if (node.isCountNode()) { 170 return false; 171 } 172 173 if (node.isAggregateNode()) { 174 return hasOneToOneSelected(node.getLeft(), context); 176 } 177 178 if (node.isVariableNode()){ 179 return !nodeRefersToObject(node, context); 180 } 181 182 if (node.isConstructorNode()) { 183 List args = ((ConstructorNode)node).getConstructorItems(); 184 for (Iterator i = args.iterator(); i.hasNext();) { 185 Node arg = (Node)i.next(); 186 if (hasOneToOneSelected(arg, context)) { 187 return true; 188 } 189 } 190 return false; 191 } 192 193 return !selectingDirectToField(node, context); 195 } 196 197 204 public void verifySelectedAlias(GenerationContext context) { 205 for (Iterator i = selectExpressions.iterator(); i.hasNext();) { 206 Node node = (Node)i.next(); 207 if (node.isDotNode()) { 209 return; 210 } 211 node.resolveClass(context); 212 } 213 } 214 215 221 public boolean isSelected(String variableName) { 222 for (Iterator i = selectExpressions.iterator(); i.hasNext();) { 223 Node node = (Node)i.next(); 224 if (node.isVariableNode() && 226 ((VariableNode)node).getCanonicalVariableName().equals(variableName)) { 227 return true; 228 } 229 } 230 return false; 231 } 232 233 public boolean isSelectNode() { 234 return true; 235 } 236 237 241 public void validate(ParseTreeContext context) { 242 for (Iterator i = selectExpressions.iterator(); i.hasNext(); ) { 243 Node item = (Node)i.next(); 244 item.validate(context); 245 } 246 } 247 248 251 public Class resolveClass(GenerationContext context) { 252 return getReferenceClass(context); 253 } 254 255 259 public Expression generateExpression(GenerationContext context) { 260 return null; 261 } 262 263 268 public Class getReferenceClass(GenerationContext context) { 269 return getClassOfFirstVariable(context); 270 } 271 272 273 private Class getClassOfFirstVariable(GenerationContext context) { 274 Class clazz = null; 275 String variable = getParseTree().getFromNode().getFirstVariable(); 276 ParseTreeContext parseTreeContext = context.getParseTreeContext(); 277 if (parseTreeContext.isRangeVariable(variable)) { 278 String schema = parseTreeContext.schemaForVariable(variable); 279 clazz = parseTreeContext.classForSchemaName(schema, context); 282 } else { 283 Node path = parseTreeContext.pathForVariable(variable); 286 clazz = path.resolveClass(context); 287 } 288 return clazz; 289 } 290 291 295 public boolean isVariableInINClauseSelected(GenerationContext context) { 296 for (Iterator i = selectExpressions.iterator(); i.hasNext();) { 297 Node node = (Node)i.next(); 298 299 if (node.isVariableNode()) { 300 String variableNameForLeft = ((VariableNode)node).getCanonicalVariableName(); 301 if (!context.getParseTreeContext().isRangeVariable(variableNameForLeft)) { 302 return true; 303 } 304 } 305 } 306 return false; 307 } 308 309 315 public boolean nodeRefersToObject(Node node, GenerationContext context) { 316 if (!node.isVariableNode()){ 317 return false; 318 } 319 String name = ((VariableNode)node).getCanonicalVariableName(); 320 String alias = context.getParseTreeContext().schemaForVariable(name); 321 if (alias != null){ 322 ClassDescriptor descriptor = context.getSession().getDescriptorForAlias(alias); 323 if (descriptor != null){ 324 return true; 325 } 326 } 327 return false; 328 } 329 330 333 private boolean selectingRelationshipField(Node node, GenerationContext context) { 334 if ((node == null) || !node.isDotNode()) { 335 return false; 336 } 337 return !((DotNode)node).endsWithDirectToField(context); 338 } 339 340 346 private boolean selectingDirectToField(Node node, GenerationContext context) { 347 348 if ((node == null) || !node.isDotNode()) { 349 return false; 350 } 351 return ((DotNode)node).endsWithDirectToField(context); 352 } 353 354 357 private Node getFirstSelectExpressionNode() { 358 return selectExpressions.size() > 0 ? 359 (Node)selectExpressions.get(0) : null; 360 } 361 362 363 private boolean isSingleSelectExpression() { 364 return selectExpressions.size() == 1; 365 } 366 367 368 } 369 | Popular Tags |