Esempio n. 1
0
  private void doPathExpression(String token, QueryTranslatorImpl q) throws QueryException {

    preprocess(token, q);

    StringTokenizer tokens = new StringTokenizer(token, ".", true);
    pathExpressionParser.start(q);
    while (tokens.hasMoreTokens()) {
      pathExpressionParser.token(tokens.nextToken(), q);
    }
    pathExpressionParser.end(q);
    if (pathExpressionParser.isCollectionValued()) {
      openExpression(q, "");
      appendToken(q, pathExpressionParser.getCollectionSubquery(q.getEnabledFilters()));
      closeExpression(q, "");
      // this is ugly here, but needed because its a subquery
      q.addQuerySpaces(
          q.getCollectionPersister(pathExpressionParser.getCollectionRole()).getCollectionSpaces());
    } else {
      if (pathExpressionParser.isExpectingCollectionIndex()) {
        expectingIndex++;
      } else {
        addJoin(pathExpressionParser.getWhereJoin(), q);
        appendToken(q, pathExpressionParser.getWhereColumn());
      }
    }
  }
  private void prepareForIndex(QueryTranslatorImpl q) throws QueryException {

    QueryableCollection collPersister = q.getCollectionPersister(collectionRole);

    if (!collPersister.hasIndex())
      throw new QueryException("unindexed collection before []: " + path);
    String[] indexCols = collPersister.getIndexColumnNames();
    if (indexCols.length != 1) throw new QueryException("composite-index appears in []: " + path);
    // String[] keyCols = collPersister.getKeyColumnNames();

    JoinSequence fromJoins =
        new JoinSequence(q.getFactory())
            .setUseThetaStyle(useThetaStyleJoin)
            .setRoot(collPersister, collectionName)
            .setNext(joinSequence.copy());

    if (!continuation) addJoin(collectionName, collPersister.getCollectionType());

    joinSequence.addCondition(
        collectionName + '.' + indexCols[0] + " = "); // TODO: get SQL rendering out of here

    CollectionElement elem = new CollectionElement();
    elem.elementColumns = collPersister.getElementColumnNames(collectionName);
    elem.elementType = collPersister.getElementType();
    elem.isOneToMany = collPersister.isOneToMany();
    elem.alias = collectionName;
    elem.joinSequence = joinSequence;
    collectionElements.addLast(elem);
    setExpectingCollectionIndex();

    q.addCollection(collectionName, collectionRole);
    q.addFromJoinOnly(collectionName, fromJoins);
  }
 public void fetch(QueryTranslatorImpl q, String entityName) throws QueryException {
   if (isCollectionValued()) {
     q.setCollectionToFetch(
         getCollectionRole(), getCollectionName(), getCollectionOwnerName(), entityName);
   } else {
     q.addEntityToFetch(entityName, getOneToOneOwnerName(), getOwnerAssociationType());
   }
 }
Esempio n. 4
0
 private void addJoin(JoinSequence joinSequence, QueryTranslatorImpl q) throws QueryException {
   // JoinFragment fromClause = q.createJoinFragment(true);
   // fromClause.addJoins( join.toJoinFragment().toFromFragmentString(), StringHelper.EMPTY_STRING
   // );
   q.addFromJoinOnly(pathExpressionParser.getName(), joinSequence);
   try {
     addToCurrentJoin(
         joinSequence.toJoinFragment(q.getEnabledFilters(), true).toWhereFragmentString());
   } catch (MappingException me) {
     throw new QueryException(me);
   }
 }
 private void dereferenceCollection(String propertyName, String role, QueryTranslatorImpl q)
     throws QueryException {
   collectionRole = role;
   QueryableCollection collPersister = q.getCollectionPersister(role);
   String name = q.createNameForCollection(role);
   addJoin(name, collPersister.getCollectionType());
   // if ( collPersister.hasWhere() ) join.addCondition( collPersister.getSQLWhereString(name) );
   collectionName = name;
   collectionOwnerName = currentName;
   currentName = name;
   currentProperty = propertyName;
   componentPath.setLength(0);
   currentPropertyMapping = new CollectionPropertyMapping(collPersister);
 }
 String continueFromManyToMany(String entityName, String[] joinColumns, QueryTranslatorImpl q)
     throws QueryException {
   start(q);
   continuation = true;
   currentName = q.createNameFor(entityName);
   q.addType(currentName, entityName);
   Queryable classPersister = q.getEntityPersister(entityName);
   // QueryJoinFragment join = q.createJoinFragment(useThetaStyleJoin);
   addJoin(
       currentName,
       q.getFactory().getTypeResolver().getTypeFactory().manyToOne(entityName),
       joinColumns);
   currentPropertyMapping = classPersister;
   return currentName;
 }
 private String getRole(String name) {
   String role = (String) collections.get(name);
   if (role == null && superQuery != null) {
     role = superQuery.getRole(name);
   }
   return role;
 }
Esempio n. 8
0
 void appendToken(QueryTranslatorImpl q, String token) {
   if (expectingIndex > 0) {
     pathExpressionParser.setLastCollectionElementIndexValue(token);
   } else {
     q.appendWhereToken(token);
   }
 }
 private String getType(String name) {
   String type = (String) typeMap.get(name);
   if (type == null && superQuery != null) {
     type = superQuery.getType(name);
   }
   return type;
 }
Esempio n. 10
0
 /**
  * Compile a subquery.
  *
  * @param superquery The containing query of the query to be compiled.
  * @throws org.hibernate.MappingException Indicates problems resolving things referenced in the
  *     query.
  * @throws org.hibernate.QueryException Generally some form of syntatic failure.
  */
 void compile(QueryTranslatorImpl superquery) throws QueryException, MappingException {
   this.tokenReplacements = superquery.tokenReplacements;
   this.superQuery = superquery;
   this.shallowQuery = true;
   this.enabledFilters = superquery.getEnabledFilters();
   compile();
 }
 public void start(QueryTranslatorImpl q) {
   if (!continuation) {
     reset(q);
     path.setLength(0);
     joinSequence = new JoinSequence(q.getFactory()).setUseThetaStyle(useThetaStyleJoin);
   }
 }
 public String addFromAssociation(QueryTranslatorImpl q) throws QueryException {
   if (isCollectionValued()) {
     return addFromCollection(q);
   } else {
     q.addFrom(currentName, joinSequence);
     return currentName;
   }
 }
Esempio n. 13
0
 public String getAliasName(String alias) {
   String name = (String) aliasNames.get(alias);
   if (name == null) {
     if (superQuery != null) {
       name = superQuery.getAliasName(alias);
     } else {
       name = alias;
     }
   }
   return name;
 }
  private void dereferenceEntity(
      String propertyName, EntityType propertyType, QueryTranslatorImpl q) throws QueryException {
    // NOTE: we avoid joining to the next table if the named property is just the foreign key value

    // if its "id"
    boolean isIdShortcut =
        EntityPersister.ENTITY_ID.equals(propertyName) && propertyType.isReferenceToPrimaryKey();

    // or its the id property name
    final String idPropertyName;
    try {
      idPropertyName = propertyType.getIdentifierOrUniqueKeyPropertyName(q.getFactory());
    } catch (MappingException me) {
      throw new QueryException(me);
    }
    boolean isNamedIdPropertyShortcut =
        idPropertyName != null
            && idPropertyName.equals(propertyName)
            && propertyType.isReferenceToPrimaryKey();

    if (isIdShortcut || isNamedIdPropertyShortcut) {
      // special shortcut for id properties, skip the join!
      // this must only occur at the _end_ of a path expression
      if (componentPath.length() > 0) componentPath.append('.');
      componentPath.append(propertyName);
    } else {
      String entityClass = propertyType.getAssociatedEntityName();
      String name = q.createNameFor(entityClass);
      q.addType(name, entityClass);
      addJoin(name, propertyType);
      if (propertyType.isOneToOne()) oneToOneOwnerName = currentName;
      ownerAssociationType = propertyType;
      currentName = name;
      currentProperty = propertyName;
      q.addPathAliasAndJoin(
          path.substring(0, path.toString().lastIndexOf('.')), name, joinSequence.copy());
      componentPath.setLength(0);
      currentPropertyMapping = q.getEntityPersister(entityClass);
    }
  }
  public String addFromCollection(QueryTranslatorImpl q) throws QueryException {
    Type collectionElementType = getPropertyType();

    if (collectionElementType == null) {
      throw new QueryException(
          "must specify 'elements' for collection valued property in from clause: " + path);
    }

    if (collectionElementType.isEntityType()) {
      // an association
      QueryableCollection collectionPersister = q.getCollectionPersister(collectionRole);
      Queryable entityPersister = (Queryable) collectionPersister.getElementPersister();
      String clazz = entityPersister.getEntityName();

      final String elementName;
      if (collectionPersister.isOneToMany()) {
        elementName = collectionName;
        // allow index() function:
        q.decoratePropertyMapping(elementName, collectionPersister);
      } else { // many-to-many
        q.addCollection(collectionName, collectionRole);
        elementName = q.createNameFor(clazz);
        addJoin(elementName, (AssociationType) collectionElementType);
      }
      q.addFrom(elementName, clazz, joinSequence);
      currentPropertyMapping = new CollectionPropertyMapping(collectionPersister);
      return elementName;
    } else {
      // collections of values
      q.addFromCollection(collectionName, collectionRole, joinSequence);
      return collectionName;
    }
  }
Esempio n. 16
0
  private void doToken(String token, QueryTranslatorImpl q) throws QueryException {
    if (q.isName(StringHelper.root(token))) { // path expression
      doPathExpression(q.unalias(token), q);
    } else if (token.startsWith(ParserHelper.HQL_VARIABLE_PREFIX)) { // named query parameter
      q.addNamedParameter(token.substring(1));
      appendToken(q, "?");
    } else {
      Queryable persister = q.getEntityPersisterUsingImports(token);
      if (persister != null) { // the name of a class
        final String discrim = persister.getDiscriminatorSQLValue();
        if (InFragment.NULL.equals(discrim) || InFragment.NOT_NULL.equals(discrim)) {
          throw new QueryException("subclass test not allowed for null or not null discriminator");
        } else {
          appendToken(q, discrim);
        }
      } else {
        Object constant;
        if (token.indexOf('.') > -1
            && (constant =
                    ReflectHelper.getConstantValue(
                        token,
                        q.getFactory().getServiceRegistry().getService(ClassLoaderService.class)))
                != null) {
          Type type;
          try {
            type = q.getFactory().getTypeResolver().heuristicType(constant.getClass().getName());
          } catch (MappingException me) {
            throw new QueryException(me);
          }
          if (type == null) {
            throw new QueryException(QueryTranslator.ERROR_CANNOT_DETERMINE_TYPE + token);
          }
          try {
            //noinspection unchecked
            appendToken(
                q, ((LiteralType) type).objectToSQLString(constant, q.getFactory().getDialect()));
          } catch (Exception e) {
            throw new QueryException(QueryTranslator.ERROR_CANNOT_FORMAT_LITERAL + token, e);
          }
        } else { // anything else

          String negatedToken = negated ? NEGATIONS.get(token.toLowerCase(Locale.ROOT)) : null;
          if (negatedToken != null && (!betweenSpecialCase || !"or".equals(negatedToken))) {
            appendToken(q, negatedToken);
          } else {
            appendToken(q, token);
          }
        }
      }
    }
  }
Esempio n. 17
0
 void addNamedParameter(String name) {
   if (superQuery != null) superQuery.addNamedParameter(name);
   Integer loc = parameterCount++;
   Object o = namedParameters.get(name);
   if (o == null) {
     namedParameters.put(name, loc);
   } else if (o instanceof Integer) {
     ArrayList list = new ArrayList(4);
     list.add(o);
     list.add(loc);
     namedParameters.put(name, list);
   } else {
     ((ArrayList) o).add(loc);
   }
 }
  public void end(QueryTranslatorImpl q) throws QueryException {
    ignoreInitialJoin = false;

    Type propertyType = getPropertyType();
    if (propertyType != null && propertyType.isCollectionType()) {
      collectionRole = ((CollectionType) propertyType).getRole();
      collectionName = q.createNameForCollection(collectionRole);
      prepareForIndex(q);
    } else {
      columns = currentColumns();
      setType();
    }

    // important!!
    continuation = false;
  }
Esempio n. 19
0
 boolean isName(String name) {
   return aliasNames.containsKey(name)
       || typeMap.containsKey(name)
       || collections.containsKey(name)
       || (superQuery != null && superQuery.isName(name));
 }
  public void token(String token, QueryTranslatorImpl q) throws QueryException {

    if (token != null) path.append(token);

    String alias = q.getPathAlias(path.toString());
    if (alias != null) {
      reset(q); // reset the dotcount (but not the path)
      currentName = alias; // after reset!
      currentPropertyMapping = q.getPropertyMapping(currentName);
      if (!ignoreInitialJoin) {
        JoinSequence ojf = q.getPathJoin(path.toString());
        try {
          joinSequence.addCondition(
              ojf.toJoinFragment(q.getEnabledFilters(), true)
                  .toWhereFragmentString()); // after reset!
        } catch (MappingException me) {
          throw new QueryException(me);
        }
        // we don't need to worry about any condition in the ON clause
        // here (toFromFragmentString), since anything in the ON condition
        // is already applied to the whole query
      }
    } else if (".".equals(token)) {
      dotcount++;
    } else {
      if (dotcount == 0) {
        if (!continuation) {
          if (!q.isName(token)) throw new QueryException("undefined alias: " + token);
          currentName = token;
          currentPropertyMapping = q.getPropertyMapping(currentName);
        }
      } else if (dotcount == 1) {
        if (currentName != null) {
          currentProperty = token;
        } else if (collectionName != null) {
          // processCollectionProperty(token, q.getCollectionPersister(collectionRole),
          // collectionName);
          continuation = false;
        } else {
          throw new QueryException("unexpected");
        }
      } else { // dotcount>=2

        // Do the corresponding RHS
        Type propertyType = getPropertyType();

        if (propertyType == null) {
          throw new QueryException("unresolved property: " + path);
        }

        if (propertyType.isComponentType()) {
          dereferenceComponent(token);
        } else if (propertyType.isEntityType()) {
          if (!isCollectionValued()) dereferenceEntity(token, (EntityType) propertyType, q);
        } else if (propertyType.isCollectionType()) {
          dereferenceCollection(token, ((CollectionType) propertyType).getRole(), q);

        } else {
          if (token != null) throw new QueryException("dereferenced: " + path);
        }
      }
    }
  }
 public void addAssociation(QueryTranslatorImpl q) throws QueryException {
   q.addJoin(getName(), joinSequence);
 }
Esempio n. 22
0
 void addQuerySpaces(Serializable[] spaces) {
   for (int i = 0; i < spaces.length; i++) {
     querySpaces.add(spaces[i]);
   }
   if (superQuery != null) superQuery.addQuerySpaces(spaces);
 }
Esempio n. 23
0
  public void token(String token, QueryTranslatorImpl q) throws QueryException {
    String lcToken = token.toLowerCase(Locale.ROOT);

    // Cope with [,]
    if (token.equals("[") && !expectingPathContinuation) {
      expectingPathContinuation = false;
      if (expectingIndex == 0) {
        throw new QueryException("unexpected [");
      }
      return;
    } else if (token.equals("]")) {
      expectingIndex--;
      expectingPathContinuation = true;
      return;
    }

    // Cope with a continued path expression (ie. ].baz)
    if (expectingPathContinuation) {
      boolean pathExpressionContinuesFurther = continuePathExpression(token, q);
      if (pathExpressionContinuesFurther) {
        return; // NOTE: early return
      }
    }

    // Cope with a subselect
    if (!inSubselect && (lcToken.equals("select") || lcToken.equals("from"))) {
      inSubselect = true;
      subselect = new StringBuilder(20);
    }
    if (inSubselect && token.equals(")")) {
      bracketsSinceSelect--;

      if (bracketsSinceSelect == -1) {
        QueryTranslatorImpl subq =
            new QueryTranslatorImpl(subselect.toString(), q.getEnabledFilters(), q.getFactory());
        try {
          subq.compile(q);
        } catch (MappingException me) {
          throw new QueryException("MappingException occurred compiling subquery", me);
        }
        appendToken(q, subq.getSQLString());
        inSubselect = false;
        bracketsSinceSelect = 0;
      }
    }
    if (inSubselect) {
      if (token.equals("(")) {
        bracketsSinceSelect++;
      }
      subselect.append(token).append(' ');
      return;
    }

    // Cope with special cases of AND, NOT, ()
    specialCasesBefore(lcToken);

    // Close extra brackets we opened
    if (!betweenSpecialCase && EXPRESSION_TERMINATORS.contains(lcToken)) {
      closeExpression(q, lcToken);
    }

    // take note when this is a boolean expression
    if (BOOLEAN_OPERATORS.contains(lcToken)) {
      booleanTests.removeLast();
      booleanTests.addLast(Boolean.TRUE);
    }

    if (lcToken.equals("not")) {
      nots.addLast(!(nots.removeLast()));
      negated = !negated;
      return; // NOTE: early return
    }

    // process a token, mapping OO path expressions to SQL expressions
    doToken(token, q);

    // Open any extra brackets we might need.
    if (!betweenSpecialCase && EXPRESSION_OPENERS.contains(lcToken)) {
      openExpression(q, lcToken);
    }

    // Cope with special cases of AND, NOT, )
    specialCasesAfter(lcToken);
  }