Package org.hibernate.hql.internal.ast.tree

Examples of org.hibernate.hql.internal.ast.tree.InsertStatement


    postProcessDML( (DeleteStatement) delete );
  }

  @Override
  protected void postProcessInsert(AST insert) throws SemanticException, QueryException {
    InsertStatement insertStatement = (InsertStatement) insert;
    insertStatement.validate();

    SelectClause selectClause = insertStatement.getSelectClause();
    Queryable persister = insertStatement.getIntoClause().getQueryable();

    if ( !insertStatement.getIntoClause().isExplicitIdInsertion() ) {
      // the insert did not explicitly reference the id.  See if
      //    1) that is allowed
      //    2) whether we need to alter the SQL tree to account for id
      final IdentifierGenerator generator = persister.getIdentifierGenerator();
      if ( !BulkInsertionCapableIdentifierGenerator.class.isInstance( generator ) ) {
        throw new QueryException(
            "Invalid identifier generator encountered for implicit id handling as part of bulk insertions"
        );
      }
      final BulkInsertionCapableIdentifierGenerator capableGenerator =
          BulkInsertionCapableIdentifierGenerator.class.cast( generator );
      if ( !capableGenerator.supportsBulkInsertionIdentifierGeneration() ) {
        throw new QueryException(
            "Identifier generator reported it does not support implicit id handling as part of bulk insertions"
        );
      }

      final String fragment = capableGenerator.determineBulkInsertionIdentifierGenerationSelectFragment(
          sessionFactoryHelper.getFactory().getDialect()
      );
      if ( fragment != null ) {
        // we got a fragment from the generator, so alter the sql tree...
        //
        // first, wrap the fragment as a node
        AST fragmentNode = getASTFactory().create( HqlSqlTokenTypes.SQL_TOKEN, fragment );
        // next, rearrange the SQL tree to add the fragment node as the first select expression
        AST originalFirstSelectExprNode = selectClause.getFirstChild();
        selectClause.setFirstChild( fragmentNode );
        fragmentNode.setNextSibling( originalFirstSelectExprNode );
        // finally, prepend the id column name(s) to the insert-spec
        insertStatement.getIntoClause().prependIdColumnSpec();
      }
    }

    if ( sessionFactoryHelper.getFactory().getDialect().supportsParametersInInsertSelect() ) {
      AST child = selectClause.getFirstChild();
      int i = 0;
      while ( child != null ) {
        if ( child instanceof ParameterNode ) {
          // infer the parameter type from the type listed in the INSERT INTO clause
          ( (ParameterNode) child ).setExpectedType(
              insertStatement.getIntoClause()
                  .getInsertionTypes()[selectClause.getParameterPositions().get( i )]
          );
          i++;
        }
        child = child.getNextSibling();
      }
    }

    final boolean includeVersionProperty = persister.isVersioned() &&
        !insertStatement.getIntoClause().isExplicitVersionInsertion() &&
        persister.isVersionPropertyInsertable();
    if ( includeVersionProperty ) {
      // We need to seed the version value as part of this bulk insert
      VersionType versionType = persister.getVersionType();
      AST versionValueNode = null;

      if ( sessionFactoryHelper.getFactory().getDialect().supportsParametersInInsertSelect() ) {
        int[] sqlTypes = versionType.sqlTypes( sessionFactoryHelper.getFactory() );
        if ( sqlTypes == null || sqlTypes.length == 0 ) {
          throw new IllegalStateException( versionType.getClass() + ".sqlTypes() returns null or empty array" );
        }
        if ( sqlTypes.length > 1 ) {
          throw new IllegalStateException(
              versionType.getClass() +
                  ".sqlTypes() returns > 1 element; only single-valued versions are allowed."
          );
        }
        versionValueNode = getASTFactory().create( HqlSqlTokenTypes.PARAM, "?" );
        ParameterSpecification paramSpec = new VersionTypeSeedParameterSpecification( versionType );
        ( (ParameterNode) versionValueNode ).setHqlParameterSpecification( paramSpec );
        parameters.add( 0, paramSpec );

        if ( sessionFactoryHelper.getFactory().getDialect().requiresCastingOfParametersInSelectClause() ) {
          // we need to wrtap the param in a cast()
          MethodNode versionMethodNode = (MethodNode) getASTFactory().create(
              HqlSqlTokenTypes.METHOD_CALL,
              "("
          );
          AST methodIdentNode = getASTFactory().create( HqlSqlTokenTypes.IDENT, "cast" );
          versionMethodNode.addChild( methodIdentNode );
          versionMethodNode.initializeMethodNode( methodIdentNode, true );
          AST castExprListNode = getASTFactory().create( HqlSqlTokenTypes.EXPR_LIST, "exprList" );
          methodIdentNode.setNextSibling( castExprListNode );
          castExprListNode.addChild( versionValueNode );
          versionValueNode.setNextSibling(
              getASTFactory().create(
                  HqlSqlTokenTypes.IDENT,
                  sessionFactoryHelper.getFactory().getDialect().getTypeName( sqlTypes[0] )
              )
          );
          processFunction( versionMethodNode, true );
          versionValueNode = versionMethodNode;
        }
      }
      else {
        if ( isIntegral( versionType ) ) {
          try {
            Object seedValue = versionType.seed( null );
            versionValueNode = getASTFactory().create( HqlSqlTokenTypes.SQL_TOKEN, seedValue.toString() );
          }
          catch (Throwable t) {
            throw new QueryException( "could not determine seed value for version on bulk insert [" + versionType + "]" );
          }
        }
        else if ( isDatabaseGeneratedTimestamp( versionType ) ) {
          String functionName = sessionFactoryHelper.getFactory()
              .getDialect()
              .getCurrentTimestampSQLFunctionName();
          versionValueNode = getASTFactory().create( HqlSqlTokenTypes.SQL_TOKEN, functionName );
        }
        else {
          throw new QueryException( "cannot handle version type [" + versionType + "] on bulk inserts with dialects not supporting parameters in insert-select statements" );
        }
      }

      AST currentFirstSelectExprNode = selectClause.getFirstChild();
      selectClause.setFirstChild( versionValueNode );
      versionValueNode.setNextSibling( currentFirstSelectExprNode );

      insertStatement.getIntoClause().prependVersionColumnSpec();
    }

    if ( insertStatement.getIntoClause().isDiscriminated() ) {
      String sqlValue = insertStatement.getIntoClause().getQueryable().getDiscriminatorSQLValue();
      AST discrimValue = getASTFactory().create( HqlSqlTokenTypes.SQL_TOKEN, sqlValue );
      insertStatement.getSelectClause().addChild( discrimValue );
    }

  }
View Full Code Here


            || PostInsertIdentifierGenerator.class.isAssignableFrom( generator.getClass() );
  }

  @Override
    protected void postProcessInsert(AST insert) throws SemanticException, QueryException {
    InsertStatement insertStatement = ( InsertStatement ) insert;
    insertStatement.validate();

    SelectClause selectClause = insertStatement.getSelectClause();
    Queryable persister = insertStatement.getIntoClause().getQueryable();

    if ( !insertStatement.getIntoClause().isExplicitIdInsertion() ) {
      // We need to generate ids as part of this bulk insert.
      //
      // Note that this is only supported for sequence-style generators and
      // post-insert-style generators; basically, only in-db generators
      IdentifierGenerator generator = persister.getIdentifierGenerator();
      if ( !supportsIdGenWithBulkInsertion( generator ) ) {
        throw new QueryException( "can only generate ids as part of bulk insert with either sequence or post-insert style generators" );
      }

      AST idSelectExprNode = null;

      if ( SequenceGenerator.class.isAssignableFrom( generator.getClass() ) ) {
        String seqName = ( String ) ( ( SequenceGenerator ) generator ).generatorKey();
        String nextval = sessionFactoryHelper.getFactory().getDialect().getSelectSequenceNextValString( seqName );
        idSelectExprNode = getASTFactory().create( HqlSqlTokenTypes.SQL_TOKEN, nextval );
      }
      else {
        //Don't need this, because we should never ever be selecting no columns in an insert ... select...
        //and because it causes a bug on DB2
        /*String idInsertString = sessionFactoryHelper.getFactory().getDialect().getIdentityInsertString();
        if ( idInsertString != null ) {
          idSelectExprNode = getASTFactory().create( HqlSqlTokenTypes.SQL_TOKEN, idInsertString );
        }*/
      }

      if ( idSelectExprNode != null ) {
        AST currentFirstSelectExprNode = selectClause.getFirstChild();
        selectClause.setFirstChild( idSelectExprNode );
        idSelectExprNode.setNextSibling( currentFirstSelectExprNode );

        insertStatement.getIntoClause().prependIdColumnSpec();
      }
    }

    final boolean includeVersionProperty = persister.isVersioned() &&
        !insertStatement.getIntoClause().isExplicitVersionInsertion() &&
        persister.isVersionPropertyInsertable();
    if ( includeVersionProperty ) {
      // We need to seed the version value as part of this bulk insert
      VersionType versionType = persister.getVersionType();
      AST versionValueNode = null;

      if ( sessionFactoryHelper.getFactory().getDialect().supportsParametersInInsertSelect() ) {
        int sqlTypes[] = versionType.sqlTypes( sessionFactoryHelper.getFactory() );
        if ( sqlTypes == null || sqlTypes.length == 0 ) {
          throw new IllegalStateException( versionType.getClass() + ".sqlTypes() returns null or empty array" );
        }
        if ( sqlTypes.length > 1 ) {
          throw new IllegalStateException(
              versionType.getClass() +
                  ".sqlTypes() returns > 1 element; only single-valued versions are allowed."
          );
        }
        versionValueNode = getASTFactory().create( HqlSqlTokenTypes.PARAM, "?" );
        ParameterSpecification paramSpec = new VersionTypeSeedParameterSpecification( versionType );
        ( ( ParameterNode ) versionValueNode ).setHqlParameterSpecification( paramSpec );
        parameters.add( 0, paramSpec );

        if ( sessionFactoryHelper.getFactory().getDialect().requiresCastingOfParametersInSelectClause() ) {
          // we need to wrtap the param in a cast()
          MethodNode versionMethodNode = ( MethodNode ) getASTFactory().create( HqlSqlTokenTypes.METHOD_CALL, "(" );
          AST methodIdentNode = getASTFactory().create( HqlSqlTokenTypes.IDENT, "cast" );
          versionMethodNode.addChild( methodIdentNode );
          versionMethodNode.initializeMethodNode(methodIdentNode, true );
          AST castExprListNode = getASTFactory().create( HqlSqlTokenTypes.EXPR_LIST, "exprList" );
          methodIdentNode.setNextSibling( castExprListNode );
          castExprListNode.addChild( versionValueNode );
          versionValueNode.setNextSibling(
              getASTFactory().create(
                  HqlSqlTokenTypes.IDENT,
                  sessionFactoryHelper.getFactory().getDialect().getTypeName( sqlTypes[0] ) )
          );
          processFunction( versionMethodNode, true );
          versionValueNode = versionMethodNode;
        }
      }
      else {
        if ( isIntegral( versionType ) ) {
          try {
            Object seedValue = versionType.seed( null );
            versionValueNode = getASTFactory().create( HqlSqlTokenTypes.SQL_TOKEN, seedValue.toString() );
          }
          catch( Throwable t ) {
            throw new QueryException( "could not determine seed value for version on bulk insert [" + versionType + "]" );
          }
        }
        else if ( isDatabaseGeneratedTimestamp( versionType ) ) {
          String functionName = sessionFactoryHelper.getFactory().getDialect().getCurrentTimestampSQLFunctionName();
          versionValueNode = getASTFactory().create( HqlSqlTokenTypes.SQL_TOKEN, functionName );
        }
        else {
          throw new QueryException( "cannot handle version type [" + versionType + "] on bulk inserts with dialects not supporting parameters in insert-select statements" );
        }
      }

      AST currentFirstSelectExprNode = selectClause.getFirstChild();
      selectClause.setFirstChild( versionValueNode );
      versionValueNode.setNextSibling( currentFirstSelectExprNode );

      insertStatement.getIntoClause().prependVersionColumnSpec();
    }

    if ( insertStatement.getIntoClause().isDiscriminated() ) {
      String sqlValue = insertStatement.getIntoClause().getQueryable().getDiscriminatorSQLValue();
      AST discrimValue = getASTFactory().create( HqlSqlTokenTypes.SQL_TOKEN, sqlValue );
      insertStatement.getSelectClause().addChild( discrimValue );
    }

  }
View Full Code Here

    postProcessDML( ( DeleteStatement ) delete );
  }

  @Override
    protected void postProcessInsert(AST insert) throws SemanticException, QueryException {
    InsertStatement insertStatement = ( InsertStatement ) insert;
    insertStatement.validate();

    SelectClause selectClause = insertStatement.getSelectClause();
    Queryable persister = insertStatement.getIntoClause().getQueryable();

    if ( !insertStatement.getIntoClause().isExplicitIdInsertion() ) {
      // the insert did not explicitly reference the id.  See if
      //    1) that is allowed
      //    2) whether we need to alter the SQL tree to account for id
      final IdentifierGenerator generator = persister.getIdentifierGenerator();
      if ( !BulkInsertionCapableIdentifierGenerator.class.isInstance( generator ) ) {
        throw new QueryException(
            "Invalid identifier generator encountered for implicit id handling as part of bulk insertions"
        );
      }
      final BulkInsertionCapableIdentifierGenerator capableGenerator =
          BulkInsertionCapableIdentifierGenerator.class.cast( generator );
      if ( ! capableGenerator.supportsBulkInsertionIdentifierGeneration() ) {
        throw new QueryException(
            "Identifier generator reported it does not support implicit id handling as part of bulk insertions"
        );
      }

            final String fragment = capableGenerator.determineBulkInsertionIdentifierGenerationSelectFragment(
          sessionFactoryHelper.getFactory().getDialect()
      );
      if ( fragment != null ) {
                // we got a fragment from the generator, so alter the sql tree...
                //
                // first, wrap the fragment as a node
                AST fragmentNode = getASTFactory().create( HqlSqlTokenTypes.SQL_TOKEN, fragment );
                // next, rearrange the SQL tree to add the fragment node as the first select expression
                AST originalFirstSelectExprNode = selectClause.getFirstChild();
                selectClause.setFirstChild( fragmentNode );
                fragmentNode.setNextSibling( originalFirstSelectExprNode );
                // finally, prepend the id column name(s) to the insert-spec
                insertStatement.getIntoClause().prependIdColumnSpec();
      }
    }

    final boolean includeVersionProperty = persister.isVersioned() &&
        !insertStatement.getIntoClause().isExplicitVersionInsertion() &&
        persister.isVersionPropertyInsertable();
    if ( includeVersionProperty ) {
      // We need to seed the version value as part of this bulk insert
      VersionType versionType = persister.getVersionType();
      AST versionValueNode = null;

      if ( sessionFactoryHelper.getFactory().getDialect().supportsParametersInInsertSelect() ) {
        int sqlTypes[] = versionType.sqlTypes( sessionFactoryHelper.getFactory() );
        if ( sqlTypes == null || sqlTypes.length == 0 ) {
          throw new IllegalStateException( versionType.getClass() + ".sqlTypes() returns null or empty array" );
        }
        if ( sqlTypes.length > 1 ) {
          throw new IllegalStateException(
              versionType.getClass() +
                  ".sqlTypes() returns > 1 element; only single-valued versions are allowed."
          );
        }
        versionValueNode = getASTFactory().create( HqlSqlTokenTypes.PARAM, "?" );
        ParameterSpecification paramSpec = new VersionTypeSeedParameterSpecification( versionType );
        ( ( ParameterNode ) versionValueNode ).setHqlParameterSpecification( paramSpec );
        parameters.add( 0, paramSpec );

        if ( sessionFactoryHelper.getFactory().getDialect().requiresCastingOfParametersInSelectClause() ) {
          // we need to wrtap the param in a cast()
          MethodNode versionMethodNode = ( MethodNode ) getASTFactory().create( HqlSqlTokenTypes.METHOD_CALL, "(" );
          AST methodIdentNode = getASTFactory().create( HqlSqlTokenTypes.IDENT, "cast" );
          versionMethodNode.addChild( methodIdentNode );
          versionMethodNode.initializeMethodNode(methodIdentNode, true );
          AST castExprListNode = getASTFactory().create( HqlSqlTokenTypes.EXPR_LIST, "exprList" );
          methodIdentNode.setNextSibling( castExprListNode );
          castExprListNode.addChild( versionValueNode );
          versionValueNode.setNextSibling(
              getASTFactory().create(
                  HqlSqlTokenTypes.IDENT,
                  sessionFactoryHelper.getFactory().getDialect().getTypeName( sqlTypes[0] ) )
          );
          processFunction( versionMethodNode, true );
          versionValueNode = versionMethodNode;
        }
      }
      else {
        if ( isIntegral( versionType ) ) {
          try {
            Object seedValue = versionType.seed( null );
            versionValueNode = getASTFactory().create( HqlSqlTokenTypes.SQL_TOKEN, seedValue.toString() );
          }
          catch( Throwable t ) {
            throw new QueryException( "could not determine seed value for version on bulk insert [" + versionType + "]" );
          }
        }
        else if ( isDatabaseGeneratedTimestamp( versionType ) ) {
          String functionName = sessionFactoryHelper.getFactory().getDialect().getCurrentTimestampSQLFunctionName();
          versionValueNode = getASTFactory().create( HqlSqlTokenTypes.SQL_TOKEN, functionName );
        }
        else {
          throw new QueryException( "cannot handle version type [" + versionType + "] on bulk inserts with dialects not supporting parameters in insert-select statements" );
        }
      }

      AST currentFirstSelectExprNode = selectClause.getFirstChild();
      selectClause.setFirstChild( versionValueNode );
      versionValueNode.setNextSibling( currentFirstSelectExprNode );

      insertStatement.getIntoClause().prependVersionColumnSpec();
    }

    if ( insertStatement.getIntoClause().isDiscriminated() ) {
      String sqlValue = insertStatement.getIntoClause().getQueryable().getDiscriminatorSQLValue();
      AST discrimValue = getASTFactory().create( HqlSqlTokenTypes.SQL_TOKEN, sqlValue );
      insertStatement.getSelectClause().addChild( discrimValue );
    }

  }
View Full Code Here

    postProcessDML( ( DeleteStatement ) delete );
  }

  @Override
    protected void postProcessInsert(AST insert) throws SemanticException, QueryException {
    InsertStatement insertStatement = ( InsertStatement ) insert;
    insertStatement.validate();

    SelectClause selectClause = insertStatement.getSelectClause();
    Queryable persister = insertStatement.getIntoClause().getQueryable();

    if ( !insertStatement.getIntoClause().isExplicitIdInsertion() ) {
      // the insert did not explicitly reference the id.  See if
      //    1) that is allowed
      //    2) whether we need to alter the SQL tree to account for id
      final IdentifierGenerator generator = persister.getIdentifierGenerator();
      if ( !BulkInsertionCapableIdentifierGenerator.class.isInstance( generator ) ) {
        throw new QueryException(
            "Invalid identifier generator encountered for implicit id handling as part of bulk insertions"
        );
      }
      final BulkInsertionCapableIdentifierGenerator capableGenerator =
          BulkInsertionCapableIdentifierGenerator.class.cast( generator );
      if ( ! capableGenerator.supportsBulkInsertionIdentifierGeneration() ) {
        throw new QueryException(
            "Identifier generator reported it does not support implicit id handling as part of bulk insertions"
        );
      }

            final String fragment = capableGenerator.determineBulkInsertionIdentifierGenerationSelectFragment(
          sessionFactoryHelper.getFactory().getDialect()
      );
      if ( fragment != null ) {
                // we got a fragment from the generator, so alter the sql tree...
                //
                // first, wrap the fragment as a node
                AST fragmentNode = getASTFactory().create( HqlSqlTokenTypes.SQL_TOKEN, fragment );
                // next, rearrange the SQL tree to add the fragment node as the first select expression
                AST originalFirstSelectExprNode = selectClause.getFirstChild();
                selectClause.setFirstChild( fragmentNode );
                fragmentNode.setNextSibling( originalFirstSelectExprNode );
                // finally, prepend the id column name(s) to the insert-spec
                insertStatement.getIntoClause().prependIdColumnSpec();
      }
    }

    final boolean includeVersionProperty = persister.isVersioned() &&
        !insertStatement.getIntoClause().isExplicitVersionInsertion() &&
        persister.isVersionPropertyInsertable();
    if ( includeVersionProperty ) {
      // We need to seed the version value as part of this bulk insert
      VersionType versionType = persister.getVersionType();
      AST versionValueNode = null;

      if ( sessionFactoryHelper.getFactory().getDialect().supportsParametersInInsertSelect() ) {
        int sqlTypes[] = versionType.sqlTypes( sessionFactoryHelper.getFactory() );
        if ( sqlTypes == null || sqlTypes.length == 0 ) {
          throw new IllegalStateException( versionType.getClass() + ".sqlTypes() returns null or empty array" );
        }
        if ( sqlTypes.length > 1 ) {
          throw new IllegalStateException(
              versionType.getClass() +
                  ".sqlTypes() returns > 1 element; only single-valued versions are allowed."
          );
        }
        versionValueNode = getASTFactory().create( HqlSqlTokenTypes.PARAM, "?" );
        ParameterSpecification paramSpec = new VersionTypeSeedParameterSpecification( versionType );
        ( ( ParameterNode ) versionValueNode ).setHqlParameterSpecification( paramSpec );
        parameters.add( 0, paramSpec );

        if ( sessionFactoryHelper.getFactory().getDialect().requiresCastingOfParametersInSelectClause() ) {
          // we need to wrtap the param in a cast()
          MethodNode versionMethodNode = ( MethodNode ) getASTFactory().create( HqlSqlTokenTypes.METHOD_CALL, "(" );
          AST methodIdentNode = getASTFactory().create( HqlSqlTokenTypes.IDENT, "cast" );
          versionMethodNode.addChild( methodIdentNode );
          versionMethodNode.initializeMethodNode(methodIdentNode, true );
          AST castExprListNode = getASTFactory().create( HqlSqlTokenTypes.EXPR_LIST, "exprList" );
          methodIdentNode.setNextSibling( castExprListNode );
          castExprListNode.addChild( versionValueNode );
          versionValueNode.setNextSibling(
              getASTFactory().create(
                  HqlSqlTokenTypes.IDENT,
                  sessionFactoryHelper.getFactory().getDialect().getTypeName( sqlTypes[0] ) )
          );
          processFunction( versionMethodNode, true );
          versionValueNode = versionMethodNode;
        }
      }
      else {
        if ( isIntegral( versionType ) ) {
          try {
            Object seedValue = versionType.seed( null );
            versionValueNode = getASTFactory().create( HqlSqlTokenTypes.SQL_TOKEN, seedValue.toString() );
          }
          catch( Throwable t ) {
            throw new QueryException( "could not determine seed value for version on bulk insert [" + versionType + "]" );
          }
        }
        else if ( isDatabaseGeneratedTimestamp( versionType ) ) {
          String functionName = sessionFactoryHelper.getFactory().getDialect().getCurrentTimestampSQLFunctionName();
          versionValueNode = getASTFactory().create( HqlSqlTokenTypes.SQL_TOKEN, functionName );
        }
        else {
          throw new QueryException( "cannot handle version type [" + versionType + "] on bulk inserts with dialects not supporting parameters in insert-select statements" );
        }
      }

      AST currentFirstSelectExprNode = selectClause.getFirstChild();
      selectClause.setFirstChild( versionValueNode );
      versionValueNode.setNextSibling( currentFirstSelectExprNode );

      insertStatement.getIntoClause().prependVersionColumnSpec();
    }

    if ( insertStatement.getIntoClause().isDiscriminated() ) {
      String sqlValue = insertStatement.getIntoClause().getQueryable().getDiscriminatorSQLValue();
      AST discrimValue = getASTFactory().create( HqlSqlTokenTypes.SQL_TOKEN, sqlValue );
      insertStatement.getSelectClause().addChild( discrimValue );
    }

  }
View Full Code Here

    postProcessDML( ( DeleteStatement ) delete );
  }

  @Override
    protected void postProcessInsert(AST insert) throws SemanticException, QueryException {
    InsertStatement insertStatement = ( InsertStatement ) insert;
    insertStatement.validate();

    SelectClause selectClause = insertStatement.getSelectClause();
    Queryable persister = insertStatement.getIntoClause().getQueryable();

    if ( !insertStatement.getIntoClause().isExplicitIdInsertion() ) {
      // the insert did not explicitly reference the id.  See if
      //    1) that is allowed
      //    2) whether we need to alter the SQL tree to account for id
      final IdentifierGenerator generator = persister.getIdentifierGenerator();
      if ( !BulkInsertionCapableIdentifierGenerator.class.isInstance( generator ) ) {
        throw new QueryException(
            "Invalid identifier generator encountered for implicit id handling as part of bulk insertions"
        );
      }
      final BulkInsertionCapableIdentifierGenerator capableGenerator =
          BulkInsertionCapableIdentifierGenerator.class.cast( generator );
      if ( ! capableGenerator.supportsBulkInsertionIdentifierGeneration() ) {
        throw new QueryException(
            "Identifier generator reported it does not support implicit id handling as part of bulk insertions"
        );
      }

            final String fragment = capableGenerator.determineBulkInsertionIdentifierGenerationSelectFragment(
          sessionFactoryHelper.getFactory().getDialect()
      );
      if ( fragment != null ) {
                // we got a fragment from the generator, so alter the sql tree...
                //
                // first, wrap the fragment as a node
                AST fragmentNode = getASTFactory().create( HqlSqlTokenTypes.SQL_TOKEN, fragment );
                // next, rearrange the SQL tree to add the fragment node as the first select expression
                AST originalFirstSelectExprNode = selectClause.getFirstChild();
                selectClause.setFirstChild( fragmentNode );
                fragmentNode.setNextSibling( originalFirstSelectExprNode );
                // finally, prepend the id column name(s) to the insert-spec
                insertStatement.getIntoClause().prependIdColumnSpec();
      }
    }

    final boolean includeVersionProperty = persister.isVersioned() &&
        !insertStatement.getIntoClause().isExplicitVersionInsertion() &&
        persister.isVersionPropertyInsertable();
    if ( includeVersionProperty ) {
      // We need to seed the version value as part of this bulk insert
      VersionType versionType = persister.getVersionType();
      AST versionValueNode = null;

      if ( sessionFactoryHelper.getFactory().getDialect().supportsParametersInInsertSelect() ) {
        int sqlTypes[] = versionType.sqlTypes( sessionFactoryHelper.getFactory() );
        if ( sqlTypes == null || sqlTypes.length == 0 ) {
          throw new IllegalStateException( versionType.getClass() + ".sqlTypes() returns null or empty array" );
        }
        if ( sqlTypes.length > 1 ) {
          throw new IllegalStateException(
              versionType.getClass() +
                  ".sqlTypes() returns > 1 element; only single-valued versions are allowed."
          );
        }
        versionValueNode = getASTFactory().create( HqlSqlTokenTypes.PARAM, "?" );
        ParameterSpecification paramSpec = new VersionTypeSeedParameterSpecification( versionType );
        ( ( ParameterNode ) versionValueNode ).setHqlParameterSpecification( paramSpec );
        parameters.add( 0, paramSpec );

        if ( sessionFactoryHelper.getFactory().getDialect().requiresCastingOfParametersInSelectClause() ) {
          // we need to wrtap the param in a cast()
          MethodNode versionMethodNode = ( MethodNode ) getASTFactory().create( HqlSqlTokenTypes.METHOD_CALL, "(" );
          AST methodIdentNode = getASTFactory().create( HqlSqlTokenTypes.IDENT, "cast" );
          versionMethodNode.addChild( methodIdentNode );
          versionMethodNode.initializeMethodNode(methodIdentNode, true );
          AST castExprListNode = getASTFactory().create( HqlSqlTokenTypes.EXPR_LIST, "exprList" );
          methodIdentNode.setNextSibling( castExprListNode );
          castExprListNode.addChild( versionValueNode );
          versionValueNode.setNextSibling(
              getASTFactory().create(
                  HqlSqlTokenTypes.IDENT,
                  sessionFactoryHelper.getFactory().getDialect().getTypeName( sqlTypes[0] ) )
          );
          processFunction( versionMethodNode, true );
          versionValueNode = versionMethodNode;
        }
      }
      else {
        if ( isIntegral( versionType ) ) {
          try {
            Object seedValue = versionType.seed( null );
            versionValueNode = getASTFactory().create( HqlSqlTokenTypes.SQL_TOKEN, seedValue.toString() );
          }
          catch( Throwable t ) {
            throw new QueryException( "could not determine seed value for version on bulk insert [" + versionType + "]" );
          }
        }
        else if ( isDatabaseGeneratedTimestamp( versionType ) ) {
          String functionName = sessionFactoryHelper.getFactory().getDialect().getCurrentTimestampSQLFunctionName();
          versionValueNode = getASTFactory().create( HqlSqlTokenTypes.SQL_TOKEN, functionName );
        }
        else {
          throw new QueryException( "cannot handle version type [" + versionType + "] on bulk inserts with dialects not supporting parameters in insert-select statements" );
        }
      }

      AST currentFirstSelectExprNode = selectClause.getFirstChild();
      selectClause.setFirstChild( versionValueNode );
      versionValueNode.setNextSibling( currentFirstSelectExprNode );

      insertStatement.getIntoClause().prependVersionColumnSpec();
    }

    if ( insertStatement.getIntoClause().isDiscriminated() ) {
      String sqlValue = insertStatement.getIntoClause().getQueryable().getDiscriminatorSQLValue();
      AST discrimValue = getASTFactory().create( HqlSqlTokenTypes.SQL_TOKEN, sqlValue );
      insertStatement.getSelectClause().addChild( discrimValue );
    }

  }
View Full Code Here

            || PostInsertIdentifierGenerator.class.isAssignableFrom( generator.getClass() );
  }

  @Override
    protected void postProcessInsert(AST insert) throws SemanticException, QueryException {
    InsertStatement insertStatement = ( InsertStatement ) insert;
    insertStatement.validate();

    SelectClause selectClause = insertStatement.getSelectClause();
    Queryable persister = insertStatement.getIntoClause().getQueryable();

    if ( !insertStatement.getIntoClause().isExplicitIdInsertion() ) {
      // We need to generate ids as part of this bulk insert.
      //
      // Note that this is only supported for sequence-style generators and
      // post-insert-style generators; basically, only in-db generators
      IdentifierGenerator generator = persister.getIdentifierGenerator();
      if ( !supportsIdGenWithBulkInsertion( generator ) ) {
        throw new QueryException( "can only generate ids as part of bulk insert with either sequence or post-insert style generators" );
      }

      AST idSelectExprNode = null;

      if ( SequenceGenerator.class.isAssignableFrom( generator.getClass() ) ) {
        String seqName = ( String ) ( ( SequenceGenerator ) generator ).generatorKey();
        String nextval = sessionFactoryHelper.getFactory().getDialect().getSelectSequenceNextValString( seqName );
        idSelectExprNode = getASTFactory().create( HqlSqlTokenTypes.SQL_TOKEN, nextval );
      }
      else {
        //Don't need this, because we should never ever be selecting no columns in an insert ... select...
        //and because it causes a bug on DB2
        /*String idInsertString = sessionFactoryHelper.getFactory().getDialect().getIdentityInsertString();
        if ( idInsertString != null ) {
          idSelectExprNode = getASTFactory().create( HqlSqlTokenTypes.SQL_TOKEN, idInsertString );
        }*/
      }

      if ( idSelectExprNode != null ) {
        AST currentFirstSelectExprNode = selectClause.getFirstChild();
        selectClause.setFirstChild( idSelectExprNode );
        idSelectExprNode.setNextSibling( currentFirstSelectExprNode );

        insertStatement.getIntoClause().prependIdColumnSpec();
      }
    }

    final boolean includeVersionProperty = persister.isVersioned() &&
        !insertStatement.getIntoClause().isExplicitVersionInsertion() &&
        persister.isVersionPropertyInsertable();
    if ( includeVersionProperty ) {
      // We need to seed the version value as part of this bulk insert
      VersionType versionType = persister.getVersionType();
      AST versionValueNode = null;

      if ( sessionFactoryHelper.getFactory().getDialect().supportsParametersInInsertSelect() ) {
        int sqlTypes[] = versionType.sqlTypes( sessionFactoryHelper.getFactory() );
        if ( sqlTypes == null || sqlTypes.length == 0 ) {
          throw new IllegalStateException( versionType.getClass() + ".sqlTypes() returns null or empty array" );
        }
        if ( sqlTypes.length > 1 ) {
          throw new IllegalStateException(
              versionType.getClass() +
                  ".sqlTypes() returns > 1 element; only single-valued versions are allowed."
          );
        }
        versionValueNode = getASTFactory().create( HqlSqlTokenTypes.PARAM, "?" );
        ParameterSpecification paramSpec = new VersionTypeSeedParameterSpecification( versionType );
        ( ( ParameterNode ) versionValueNode ).setHqlParameterSpecification( paramSpec );
        parameters.add( 0, paramSpec );

        if ( sessionFactoryHelper.getFactory().getDialect().requiresCastingOfParametersInSelectClause() ) {
          // we need to wrtap the param in a cast()
          MethodNode versionMethodNode = ( MethodNode ) getASTFactory().create( HqlSqlTokenTypes.METHOD_CALL, "(" );
          AST methodIdentNode = getASTFactory().create( HqlSqlTokenTypes.IDENT, "cast" );
          versionMethodNode.addChild( methodIdentNode );
          versionMethodNode.initializeMethodNode(methodIdentNode, true );
          AST castExprListNode = getASTFactory().create( HqlSqlTokenTypes.EXPR_LIST, "exprList" );
          methodIdentNode.setNextSibling( castExprListNode );
          castExprListNode.addChild( versionValueNode );
          versionValueNode.setNextSibling(
              getASTFactory().create(
                  HqlSqlTokenTypes.IDENT,
                  sessionFactoryHelper.getFactory().getDialect().getTypeName( sqlTypes[0] ) )
          );
          processFunction( versionMethodNode, true );
          versionValueNode = versionMethodNode;
        }
      }
      else {
        if ( isIntegral( versionType ) ) {
          try {
            Object seedValue = versionType.seed( null );
            versionValueNode = getASTFactory().create( HqlSqlTokenTypes.SQL_TOKEN, seedValue.toString() );
          }
          catch( Throwable t ) {
            throw new QueryException( "could not determine seed value for version on bulk insert [" + versionType + "]" );
          }
        }
        else if ( isDatabaseGeneratedTimestamp( versionType ) ) {
          String functionName = sessionFactoryHelper.getFactory().getDialect().getCurrentTimestampSQLFunctionName();
          versionValueNode = getASTFactory().create( HqlSqlTokenTypes.SQL_TOKEN, functionName );
        }
        else {
          throw new QueryException( "cannot handle version type [" + versionType + "] on bulk inserts with dialects not supporting parameters in insert-select statements" );
        }
      }

      AST currentFirstSelectExprNode = selectClause.getFirstChild();
      selectClause.setFirstChild( versionValueNode );
      versionValueNode.setNextSibling( currentFirstSelectExprNode );

      insertStatement.getIntoClause().prependVersionColumnSpec();
    }

    if ( insertStatement.getIntoClause().isDiscriminated() ) {
      String sqlValue = insertStatement.getIntoClause().getQueryable().getDiscriminatorSQLValue();
      AST discrimValue = getASTFactory().create( HqlSqlTokenTypes.SQL_TOKEN, sqlValue );
      insertStatement.getSelectClause().addChild( discrimValue );
    }

  }
View Full Code Here

    postProcessDML( ( DeleteStatement ) delete );
  }

  @Override
    protected void postProcessInsert(AST insert) throws SemanticException, QueryException {
    InsertStatement insertStatement = ( InsertStatement ) insert;
    insertStatement.validate();

    SelectClause selectClause = insertStatement.getSelectClause();
    Queryable persister = insertStatement.getIntoClause().getQueryable();

    if ( !insertStatement.getIntoClause().isExplicitIdInsertion() ) {
      // the insert did not explicitly reference the id.  See if
      //    1) that is allowed
      //    2) whether we need to alter the SQL tree to account for id
      final IdentifierGenerator generator = persister.getIdentifierGenerator();
      if ( !BulkInsertionCapableIdentifierGenerator.class.isInstance( generator ) ) {
        throw new QueryException(
            "Invalid identifier generator encountered for implicit id handling as part of bulk insertions"
        );
      }
      final BulkInsertionCapableIdentifierGenerator capableGenerator =
          BulkInsertionCapableIdentifierGenerator.class.cast( generator );
      if ( ! capableGenerator.supportsBulkInsertionIdentifierGeneration() ) {
        throw new QueryException(
            "Identifier generator reported it does not support implicit id handling as part of bulk insertions"
        );
      }

            final String fragment = capableGenerator.determineBulkInsertionIdentifierGenerationSelectFragment(
          sessionFactoryHelper.getFactory().getDialect()
      );
      if ( fragment != null ) {
                // we got a fragment from the generator, so alter the sql tree...
                //
                // first, wrap the fragment as a node
                AST fragmentNode = getASTFactory().create( HqlSqlTokenTypes.SQL_TOKEN, fragment );
                // next, rearrange the SQL tree to add the fragment node as the first select expression
                AST originalFirstSelectExprNode = selectClause.getFirstChild();
                selectClause.setFirstChild( fragmentNode );
                fragmentNode.setNextSibling( originalFirstSelectExprNode );
                // finally, prepend the id column name(s) to the insert-spec
                insertStatement.getIntoClause().prependIdColumnSpec();
      }
    }

    if ( sessionFactoryHelper.getFactory().getDialect().supportsParametersInInsertSelect() ) {
      AST child = selectClause.getFirstChild();
      int i = 0;
      while(child != null) {
        if(child instanceof ParameterNode) {
          // infer the parameter type from the type listed in the INSERT INTO clause
          ((ParameterNode)child).setExpectedType(insertStatement.getIntoClause()
              .getInsertionTypes()[selectClause.getParameterPositions().get(i)]);
          i++;
        }
        child = child.getNextSibling();
      }
    }

    final boolean includeVersionProperty = persister.isVersioned() &&
        !insertStatement.getIntoClause().isExplicitVersionInsertion() &&
        persister.isVersionPropertyInsertable();
    if ( includeVersionProperty ) {
      // We need to seed the version value as part of this bulk insert
      VersionType versionType = persister.getVersionType();
      AST versionValueNode = null;

      if ( sessionFactoryHelper.getFactory().getDialect().supportsParametersInInsertSelect() ) {
        int sqlTypes[] = versionType.sqlTypes( sessionFactoryHelper.getFactory() );
        if ( sqlTypes == null || sqlTypes.length == 0 ) {
          throw new IllegalStateException( versionType.getClass() + ".sqlTypes() returns null or empty array" );
        }
        if ( sqlTypes.length > 1 ) {
          throw new IllegalStateException(
              versionType.getClass() +
                  ".sqlTypes() returns > 1 element; only single-valued versions are allowed."
          );
        }
        versionValueNode = getASTFactory().create( HqlSqlTokenTypes.PARAM, "?" );
        ParameterSpecification paramSpec = new VersionTypeSeedParameterSpecification( versionType );
        ( ( ParameterNode ) versionValueNode ).setHqlParameterSpecification( paramSpec );
        parameters.add( 0, paramSpec );

        if ( sessionFactoryHelper.getFactory().getDialect().requiresCastingOfParametersInSelectClause() ) {
          // we need to wrtap the param in a cast()
          MethodNode versionMethodNode = ( MethodNode ) getASTFactory().create( HqlSqlTokenTypes.METHOD_CALL, "(" );
          AST methodIdentNode = getASTFactory().create( HqlSqlTokenTypes.IDENT, "cast" );
          versionMethodNode.addChild( methodIdentNode );
          versionMethodNode.initializeMethodNode(methodIdentNode, true );
          AST castExprListNode = getASTFactory().create( HqlSqlTokenTypes.EXPR_LIST, "exprList" );
          methodIdentNode.setNextSibling( castExprListNode );
          castExprListNode.addChild( versionValueNode );
          versionValueNode.setNextSibling(
              getASTFactory().create(
                  HqlSqlTokenTypes.IDENT,
                  sessionFactoryHelper.getFactory().getDialect().getTypeName( sqlTypes[0] ) )
          );
          processFunction( versionMethodNode, true );
          versionValueNode = versionMethodNode;
        }
      }
      else {
        if ( isIntegral( versionType ) ) {
          try {
            Object seedValue = versionType.seed( null );
            versionValueNode = getASTFactory().create( HqlSqlTokenTypes.SQL_TOKEN, seedValue.toString() );
          }
          catch( Throwable t ) {
            throw new QueryException( "could not determine seed value for version on bulk insert [" + versionType + "]" );
          }
        }
        else if ( isDatabaseGeneratedTimestamp( versionType ) ) {
          String functionName = sessionFactoryHelper.getFactory().getDialect().getCurrentTimestampSQLFunctionName();
          versionValueNode = getASTFactory().create( HqlSqlTokenTypes.SQL_TOKEN, functionName );
        }
        else {
          throw new QueryException( "cannot handle version type [" + versionType + "] on bulk inserts with dialects not supporting parameters in insert-select statements" );
        }
      }

      AST currentFirstSelectExprNode = selectClause.getFirstChild();
      selectClause.setFirstChild( versionValueNode );
      versionValueNode.setNextSibling( currentFirstSelectExprNode );

      insertStatement.getIntoClause().prependVersionColumnSpec();
    }

    if ( insertStatement.getIntoClause().isDiscriminated() ) {
      String sqlValue = insertStatement.getIntoClause().getQueryable().getDiscriminatorSQLValue();
      AST discrimValue = getASTFactory().create( HqlSqlTokenTypes.SQL_TOKEN, sqlValue );
      insertStatement.getSelectClause().addChild( discrimValue );
    }

  }
View Full Code Here

    postProcessDML( ( DeleteStatement ) delete );
  }

  @Override
    protected void postProcessInsert(AST insert) throws SemanticException, QueryException {
    InsertStatement insertStatement = ( InsertStatement ) insert;
    insertStatement.validate();

    SelectClause selectClause = insertStatement.getSelectClause();
    Queryable persister = insertStatement.getIntoClause().getQueryable();

    if ( !insertStatement.getIntoClause().isExplicitIdInsertion() ) {
      // the insert did not explicitly reference the id.  See if
      //    1) that is allowed
      //    2) whether we need to alter the SQL tree to account for id
      final IdentifierGenerator generator = persister.getIdentifierGenerator();
      if ( !BulkInsertionCapableIdentifierGenerator.class.isInstance( generator ) ) {
        throw new QueryException(
            "Invalid identifier generator encountered for implicit id handling as part of bulk insertions"
        );
      }
      final BulkInsertionCapableIdentifierGenerator capableGenerator =
          BulkInsertionCapableIdentifierGenerator.class.cast( generator );
      if ( ! capableGenerator.supportsBulkInsertionIdentifierGeneration() ) {
        throw new QueryException(
            "Identifier generator reported it does not support implicit id handling as part of bulk insertions"
        );
      }

            final String fragment = capableGenerator.determineBulkInsertionIdentifierGenerationSelectFragment(
          sessionFactoryHelper.getFactory().getDialect()
      );
      if ( fragment != null ) {
                // we got a fragment from the generator, so alter the sql tree...
                //
                // first, wrap the fragment as a node
                AST fragmentNode = getASTFactory().create( HqlSqlTokenTypes.SQL_TOKEN, fragment );
                // next, rearrange the SQL tree to add the fragment node as the first select expression
                AST originalFirstSelectExprNode = selectClause.getFirstChild();
                selectClause.setFirstChild( fragmentNode );
                fragmentNode.setNextSibling( originalFirstSelectExprNode );
                // finally, prepend the id column name(s) to the insert-spec
                insertStatement.getIntoClause().prependIdColumnSpec();
      }
    }

    final boolean includeVersionProperty = persister.isVersioned() &&
        !insertStatement.getIntoClause().isExplicitVersionInsertion() &&
        persister.isVersionPropertyInsertable();
    if ( includeVersionProperty ) {
      // We need to seed the version value as part of this bulk insert
      VersionType versionType = persister.getVersionType();
      AST versionValueNode = null;

      if ( sessionFactoryHelper.getFactory().getDialect().supportsParametersInInsertSelect() ) {
        int sqlTypes[] = versionType.sqlTypes( sessionFactoryHelper.getFactory() );
        if ( sqlTypes == null || sqlTypes.length == 0 ) {
          throw new IllegalStateException( versionType.getClass() + ".sqlTypes() returns null or empty array" );
        }
        if ( sqlTypes.length > 1 ) {
          throw new IllegalStateException(
              versionType.getClass() +
                  ".sqlTypes() returns > 1 element; only single-valued versions are allowed."
          );
        }
        versionValueNode = getASTFactory().create( HqlSqlTokenTypes.PARAM, "?" );
        ParameterSpecification paramSpec = new VersionTypeSeedParameterSpecification( versionType );
        ( ( ParameterNode ) versionValueNode ).setHqlParameterSpecification( paramSpec );
        parameters.add( 0, paramSpec );

        if ( sessionFactoryHelper.getFactory().getDialect().requiresCastingOfParametersInSelectClause() ) {
          // we need to wrtap the param in a cast()
          MethodNode versionMethodNode = ( MethodNode ) getASTFactory().create( HqlSqlTokenTypes.METHOD_CALL, "(" );
          AST methodIdentNode = getASTFactory().create( HqlSqlTokenTypes.IDENT, "cast" );
          versionMethodNode.addChild( methodIdentNode );
          versionMethodNode.initializeMethodNode(methodIdentNode, true );
          AST castExprListNode = getASTFactory().create( HqlSqlTokenTypes.EXPR_LIST, "exprList" );
          methodIdentNode.setNextSibling( castExprListNode );
          castExprListNode.addChild( versionValueNode );
          versionValueNode.setNextSibling(
              getASTFactory().create(
                  HqlSqlTokenTypes.IDENT,
                  sessionFactoryHelper.getFactory().getDialect().getTypeName( sqlTypes[0] ) )
          );
          processFunction( versionMethodNode, true );
          versionValueNode = versionMethodNode;
        }
      }
      else {
        if ( isIntegral( versionType ) ) {
          try {
            Object seedValue = versionType.seed( null );
            versionValueNode = getASTFactory().create( HqlSqlTokenTypes.SQL_TOKEN, seedValue.toString() );
          }
          catch( Throwable t ) {
            throw new QueryException( "could not determine seed value for version on bulk insert [" + versionType + "]" );
          }
        }
        else if ( isDatabaseGeneratedTimestamp( versionType ) ) {
          String functionName = sessionFactoryHelper.getFactory().getDialect().getCurrentTimestampSQLFunctionName();
          versionValueNode = getASTFactory().create( HqlSqlTokenTypes.SQL_TOKEN, functionName );
        }
        else {
          throw new QueryException( "cannot handle version type [" + versionType + "] on bulk inserts with dialects not supporting parameters in insert-select statements" );
        }
      }

      AST currentFirstSelectExprNode = selectClause.getFirstChild();
      selectClause.setFirstChild( versionValueNode );
      versionValueNode.setNextSibling( currentFirstSelectExprNode );

      insertStatement.getIntoClause().prependVersionColumnSpec();
    }

    if ( insertStatement.getIntoClause().isDiscriminated() ) {
      String sqlValue = insertStatement.getIntoClause().getQueryable().getDiscriminatorSQLValue();
      AST discrimValue = getASTFactory().create( HqlSqlTokenTypes.SQL_TOKEN, sqlValue );
      insertStatement.getSelectClause().addChild( discrimValue );
    }

  }
View Full Code Here

    postProcessDML( ( DeleteStatement ) delete );
  }

  @Override
    protected void postProcessInsert(AST insert) throws SemanticException, QueryException {
    InsertStatement insertStatement = ( InsertStatement ) insert;
    insertStatement.validate();

    SelectClause selectClause = insertStatement.getSelectClause();
    Queryable persister = insertStatement.getIntoClause().getQueryable();

    if ( !insertStatement.getIntoClause().isExplicitIdInsertion() ) {
      // the insert did not explicitly reference the id.  See if
      //    1) that is allowed
      //    2) whether we need to alter the SQL tree to account for id
      final IdentifierGenerator generator = persister.getIdentifierGenerator();
      if ( !BulkInsertionCapableIdentifierGenerator.class.isInstance( generator ) ) {
        throw new QueryException(
            "Invalid identifier generator encountered for implicit id handling as part of bulk insertions"
        );
      }
      final BulkInsertionCapableIdentifierGenerator capableGenerator =
          BulkInsertionCapableIdentifierGenerator.class.cast( generator );
      if ( ! capableGenerator.supportsBulkInsertionIdentifierGeneration() ) {
        throw new QueryException(
            "Identifier generator reported it does not support implicit id handling as part of bulk insertions"
        );
      }

            final String fragment = capableGenerator.determineBulkInsertionIdentifierGenerationSelectFragment(
          sessionFactoryHelper.getFactory().getDialect()
      );
      if ( fragment != null ) {
                // we got a fragment from the generator, so alter the sql tree...
                //
                // first, wrap the fragment as a node
                AST fragmentNode = getASTFactory().create( HqlSqlTokenTypes.SQL_TOKEN, fragment );
                // next, rearrange the SQL tree to add the fragment node as the first select expression
                AST originalFirstSelectExprNode = selectClause.getFirstChild();
                selectClause.setFirstChild( fragmentNode );
                fragmentNode.setNextSibling( originalFirstSelectExprNode );
                // finally, prepend the id column name(s) to the insert-spec
                insertStatement.getIntoClause().prependIdColumnSpec();
      }
    }

    if ( sessionFactoryHelper.getFactory().getDialect().supportsParametersInInsertSelect() ) {
      AST child = selectClause.getFirstChild();
      int i = 0;
      while(child != null) {
        if(child instanceof ParameterNode) {
          // infer the parameter type from the type listed in the INSERT INTO clause
          ((ParameterNode)child).setExpectedType(insertStatement.getIntoClause()
              .getInsertionTypes()[selectClause.getParameterPositions().get(i)]);
          i++;
        }
        child = child.getNextSibling();
      }
    }

    final boolean includeVersionProperty = persister.isVersioned() &&
        !insertStatement.getIntoClause().isExplicitVersionInsertion() &&
        persister.isVersionPropertyInsertable();
    if ( includeVersionProperty ) {
      // We need to seed the version value as part of this bulk insert
      VersionType versionType = persister.getVersionType();
      AST versionValueNode = null;

      if ( sessionFactoryHelper.getFactory().getDialect().supportsParametersInInsertSelect() ) {
        int sqlTypes[] = versionType.sqlTypes( sessionFactoryHelper.getFactory() );
        if ( sqlTypes == null || sqlTypes.length == 0 ) {
          throw new IllegalStateException( versionType.getClass() + ".sqlTypes() returns null or empty array" );
        }
        if ( sqlTypes.length > 1 ) {
          throw new IllegalStateException(
              versionType.getClass() +
                  ".sqlTypes() returns > 1 element; only single-valued versions are allowed."
          );
        }
        versionValueNode = getASTFactory().create( HqlSqlTokenTypes.PARAM, "?" );
        ParameterSpecification paramSpec = new VersionTypeSeedParameterSpecification( versionType );
        ( ( ParameterNode ) versionValueNode ).setHqlParameterSpecification( paramSpec );
        parameters.add( 0, paramSpec );

        if ( sessionFactoryHelper.getFactory().getDialect().requiresCastingOfParametersInSelectClause() ) {
          // we need to wrtap the param in a cast()
          MethodNode versionMethodNode = ( MethodNode ) getASTFactory().create( HqlSqlTokenTypes.METHOD_CALL, "(" );
          AST methodIdentNode = getASTFactory().create( HqlSqlTokenTypes.IDENT, "cast" );
          versionMethodNode.addChild( methodIdentNode );
          versionMethodNode.initializeMethodNode(methodIdentNode, true );
          AST castExprListNode = getASTFactory().create( HqlSqlTokenTypes.EXPR_LIST, "exprList" );
          methodIdentNode.setNextSibling( castExprListNode );
          castExprListNode.addChild( versionValueNode );
          versionValueNode.setNextSibling(
              getASTFactory().create(
                  HqlSqlTokenTypes.IDENT,
                  sessionFactoryHelper.getFactory().getDialect().getTypeName( sqlTypes[0] ) )
          );
          processFunction( versionMethodNode, true );
          versionValueNode = versionMethodNode;
        }
      }
      else {
        if ( isIntegral( versionType ) ) {
          try {
            Object seedValue = versionType.seed( null );
            versionValueNode = getASTFactory().create( HqlSqlTokenTypes.SQL_TOKEN, seedValue.toString() );
          }
          catch( Throwable t ) {
            throw new QueryException( "could not determine seed value for version on bulk insert [" + versionType + "]" );
          }
        }
        else if ( isDatabaseGeneratedTimestamp( versionType ) ) {
          String functionName = sessionFactoryHelper.getFactory().getDialect().getCurrentTimestampSQLFunctionName();
          versionValueNode = getASTFactory().create( HqlSqlTokenTypes.SQL_TOKEN, functionName );
        }
        else {
          throw new QueryException( "cannot handle version type [" + versionType + "] on bulk inserts with dialects not supporting parameters in insert-select statements" );
        }
      }

      AST currentFirstSelectExprNode = selectClause.getFirstChild();
      selectClause.setFirstChild( versionValueNode );
      versionValueNode.setNextSibling( currentFirstSelectExprNode );

      insertStatement.getIntoClause().prependVersionColumnSpec();
    }

    if ( insertStatement.getIntoClause().isDiscriminated() ) {
      String sqlValue = insertStatement.getIntoClause().getQueryable().getDiscriminatorSQLValue();
      AST discrimValue = getASTFactory().create( HqlSqlTokenTypes.SQL_TOKEN, sqlValue );
      insertStatement.getSelectClause().addChild( discrimValue );
    }

  }
View Full Code Here

    postProcessDML( ( DeleteStatement ) delete );
  }

  @Override
    protected void postProcessInsert(AST insert) throws SemanticException, QueryException {
    InsertStatement insertStatement = ( InsertStatement ) insert;
    insertStatement.validate();

    SelectClause selectClause = insertStatement.getSelectClause();
    Queryable persister = insertStatement.getIntoClause().getQueryable();

    if ( !insertStatement.getIntoClause().isExplicitIdInsertion() ) {
      // the insert did not explicitly reference the id.  See if
      //    1) that is allowed
      //    2) whether we need to alter the SQL tree to account for id
      final IdentifierGenerator generator = persister.getIdentifierGenerator();
      if ( !BulkInsertionCapableIdentifierGenerator.class.isInstance( generator ) ) {
        throw new QueryException(
            "Invalid identifier generator encountered for implicit id handling as part of bulk insertions"
        );
      }
      final BulkInsertionCapableIdentifierGenerator capableGenerator =
          BulkInsertionCapableIdentifierGenerator.class.cast( generator );
      if ( ! capableGenerator.supportsBulkInsertionIdentifierGeneration() ) {
        throw new QueryException(
            "Identifier generator reported it does not support implicit id handling as part of bulk insertions"
        );
      }

            final String fragment = capableGenerator.determineBulkInsertionIdentifierGenerationSelectFragment(
          sessionFactoryHelper.getFactory().getDialect()
      );
      if ( fragment != null ) {
                // we got a fragment from the generator, so alter the sql tree...
                //
                // first, wrap the fragment as a node
                AST fragmentNode = getASTFactory().create( HqlSqlTokenTypes.SQL_TOKEN, fragment );
                // next, rearrange the SQL tree to add the fragment node as the first select expression
                AST originalFirstSelectExprNode = selectClause.getFirstChild();
                selectClause.setFirstChild( fragmentNode );
                fragmentNode.setNextSibling( originalFirstSelectExprNode );
                // finally, prepend the id column name(s) to the insert-spec
                insertStatement.getIntoClause().prependIdColumnSpec();
      }
    }

    if ( sessionFactoryHelper.getFactory().getDialect().supportsParametersInInsertSelect() ) {
      AST child = selectClause.getFirstChild();
      int i = 0;
      while(child != null) {
        if(child instanceof ParameterNode) {
          // infer the parameter type from the type listed in the INSERT INTO clause
          ((ParameterNode)child).setExpectedType(insertStatement.getIntoClause()
              .getInsertionTypes()[selectClause.getParameterPositions().get(i)]);
          i++;
        }
        child = child.getNextSibling();
      }
    }

    final boolean includeVersionProperty = persister.isVersioned() &&
        !insertStatement.getIntoClause().isExplicitVersionInsertion() &&
        persister.isVersionPropertyInsertable();
    if ( includeVersionProperty ) {
      // We need to seed the version value as part of this bulk insert
      VersionType versionType = persister.getVersionType();
      AST versionValueNode = null;

      if ( sessionFactoryHelper.getFactory().getDialect().supportsParametersInInsertSelect() ) {
        int sqlTypes[] = versionType.sqlTypes( sessionFactoryHelper.getFactory() );
        if ( sqlTypes == null || sqlTypes.length == 0 ) {
          throw new IllegalStateException( versionType.getClass() + ".sqlTypes() returns null or empty array" );
        }
        if ( sqlTypes.length > 1 ) {
          throw new IllegalStateException(
              versionType.getClass() +
                  ".sqlTypes() returns > 1 element; only single-valued versions are allowed."
          );
        }
        versionValueNode = getASTFactory().create( HqlSqlTokenTypes.PARAM, "?" );
        ParameterSpecification paramSpec = new VersionTypeSeedParameterSpecification( versionType );
        ( ( ParameterNode ) versionValueNode ).setHqlParameterSpecification( paramSpec );
        parameters.add( 0, paramSpec );

        if ( sessionFactoryHelper.getFactory().getDialect().requiresCastingOfParametersInSelectClause() ) {
          // we need to wrtap the param in a cast()
          MethodNode versionMethodNode = ( MethodNode ) getASTFactory().create( HqlSqlTokenTypes.METHOD_CALL, "(" );
          AST methodIdentNode = getASTFactory().create( HqlSqlTokenTypes.IDENT, "cast" );
          versionMethodNode.addChild( methodIdentNode );
          versionMethodNode.initializeMethodNode(methodIdentNode, true );
          AST castExprListNode = getASTFactory().create( HqlSqlTokenTypes.EXPR_LIST, "exprList" );
          methodIdentNode.setNextSibling( castExprListNode );
          castExprListNode.addChild( versionValueNode );
          versionValueNode.setNextSibling(
              getASTFactory().create(
                  HqlSqlTokenTypes.IDENT,
                  sessionFactoryHelper.getFactory().getDialect().getTypeName( sqlTypes[0] ) )
          );
          processFunction( versionMethodNode, true );
          versionValueNode = versionMethodNode;
        }
      }
      else {
        if ( isIntegral( versionType ) ) {
          try {
            Object seedValue = versionType.seed( null );
            versionValueNode = getASTFactory().create( HqlSqlTokenTypes.SQL_TOKEN, seedValue.toString() );
          }
          catch( Throwable t ) {
            throw new QueryException( "could not determine seed value for version on bulk insert [" + versionType + "]" );
          }
        }
        else if ( isDatabaseGeneratedTimestamp( versionType ) ) {
          String functionName = sessionFactoryHelper.getFactory().getDialect().getCurrentTimestampSQLFunctionName();
          versionValueNode = getASTFactory().create( HqlSqlTokenTypes.SQL_TOKEN, functionName );
        }
        else {
          throw new QueryException( "cannot handle version type [" + versionType + "] on bulk inserts with dialects not supporting parameters in insert-select statements" );
        }
      }

      AST currentFirstSelectExprNode = selectClause.getFirstChild();
      selectClause.setFirstChild( versionValueNode );
      versionValueNode.setNextSibling( currentFirstSelectExprNode );

      insertStatement.getIntoClause().prependVersionColumnSpec();
    }

    if ( insertStatement.getIntoClause().isDiscriminated() ) {
      String sqlValue = insertStatement.getIntoClause().getQueryable().getDiscriminatorSQLValue();
      AST discrimValue = getASTFactory().create( HqlSqlTokenTypes.SQL_TOKEN, sqlValue );
      insertStatement.getSelectClause().addChild( discrimValue );
    }

  }
View Full Code Here

TOP

Related Classes of org.hibernate.hql.internal.ast.tree.InsertStatement

Copyright © 2018 www.massapicom. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.