<commit_before>package ingraph.compiler.cypher2gplan.builders

import ingraph.compiler.cypher2gplan.structures.MatchDescriptor
import ingraph.compiler.cypher2gplan.util.GrammarUtil
import ingraph.model.gplan.GNode
import ingraph.model.{expr, gplan}
import org.slizaa.neo4j.opencypher.{openCypher => oc}

import scala.collection.JavaConverters._
import scala.collection.mutable
import scala.collection.mutable.ListBuffer

object StatementBuilder {
  def dispatchBuildStatement(statement: oc.Statement): gplan.GNode = {
    statement match {
      case s: oc.SingleQuery => buildStatement(s)
      case s: oc.CombinedQuery => buildStatement(s)
    }
  }

  /**
    * Transform a SinglePartQuery to a sequence of clauses.
    */
  def siglePartQuery2Clauses(spq: oc.SinglePartQuery): Seq[oc.Clause] = {
    spq match {
      case roe: oc.ReadOnlyEnd => roe.getReadPart.getReadingClause.asScala ++Seq(roe.getReturn)
      case rue: oc.ReadUpdateEnd => rue.getReadingClauses.asScala ++ rue.getUpdatingClauses.asScala ++ Seq(Option(rue.getReturn)).flatten[oc.Clause]
      case ue: oc.UpdatingEnd => Seq(ue.getUpdatingStartClause) ++ ue.getUpdatingClauses.asScala ++ Seq(Option(ue.getReturn)).flatten[oc.Clause]
    }
  }

  /**
    * Transform the first part of a MultiPartQuery to a sequence of clauses.
    */
  def multiPartQuery_FirstPart2Clauses(mpq: oc.MultiPartQuery): Seq[oc.Clause] = {
    (
      Option(mpq.getReadPart) match {
        case Some(rp) => rp.getReadingClause.asScala
        case None => Seq(mpq.getUpdatingStartClause) ++ mpq.getUpdatingPart.getUpdatingClauses.asScala
      }
    ) ++ Seq(mpq.getWithPart)
  }

  /**
    * Transform a MultiPartSubQuery(*) to a sequence of clauses.
    *
    * (*): MultiPartSubQuery is a structural sugar in the openCypher Xtext grammar
    *      not present in the original openCypher grammar
    */
  def multiPartSubQuery2Clauses(mpsq: oc.MultiPartSubQuery): Seq[oc.Clause] = {
      Seq(mpsq.getReadPart.getReadingClause.asScala, mpsq.getUpdatingPart.getUpdatingClauses.asScala).flatten[oc.Clause]
  }

  /** Builds the gplan for a single query built from several query parts.
    */
  def buildStatement(q: oc.SingleQuery): gplan.GNode = {
    // Compiled form of the query is the chain of the query parts.
    // The first query part will receive a dual object source there.
    // Accumulate tree built from successive query parts in result
    var result: gplan.GNode = gplan.Dual()

    // Do some checks on the clauses of the single query
    //FIXME: Validator.checkSingleQueryClauseSequence(clauses, ce.l)
    // A query part should have the form (MATCH*)((CREATE|DELETE)+ RETURN?|(WITH UNWIND?)|UNWIND|RETURN)

    q match {
      case spq: oc.SinglePartQuery => {
        val clauses: Seq[oc.Clause] = siglePartQuery2Clauses(spq)
        result = buildQueryPart(clauses, result)
      }
      case mpq: oc.MultiPartQuery => {
        result = buildQueryPart(multiPartQuery_FirstPart2Clauses(mpq), result)

        for (queryPart <- mpq.getSubQueries.asScala) {
          result = buildQueryPart(multiPartSubQuery2Clauses(queryPart), result)
        }

        result = buildQueryPart(siglePartQuery2Clauses(mpq.getSinglePartQuery), result)
      }
    }

    result
  }

  def buildStatement(q: oc.CombinedQuery): gplan.GNode = {
    var result = buildStatement(q.getSingleQuery)

    for (u <- q.getUnion.asScala) {
      result = gplan.Union(u.isAll, result, buildStatement(u.getSingleQuery))
    }

    // FIXME: validator
    //		if (!Validator.checkIfUnionQueryColumnNamesMatch(result, ce.l)) {
    //			ce.l.unrecoverableError('''All sub queries of a UNION query must have the same column aliases.''')
    //		}
<commit_msg>Adjust compiler to the oC M10 Xtext grammar<commit_after>package ingraph.compiler.cypher2gplan.builders

import ingraph.compiler.cypher2gplan.structures.MatchDescriptor
import ingraph.compiler.cypher2gplan.util.GrammarUtil
import ingraph.model.gplan.GNode
import ingraph.model.{expr, gplan}
import org.slizaa.neo4j.opencypher.{openCypher => oc}

import scala.collection.JavaConverters._
import scala.collection.mutable
import scala.collection.mutable.ListBuffer

object StatementBuilder {
  def dispatchBuildStatement(statement: oc.Statement): gplan.GNode = {
    statement match {
      case s: oc.SingleQuery => buildStatement(s)
      case s: oc.CombinedQuery => buildStatement(s)
    }
  }

  /**
    * Transform a SinglePartQuery to a sequence of clauses.
    */
  def siglePartQuery2Clauses(spq: oc.SinglePartQuery): Seq[oc.Clause] = {
    spq.getReadingClauses.asScala ++ spq.getUpdatingClauses.asScala :+ spq.getReturn
  }

  /**
    * Transform a MultiPartSubQuery(*) to a sequence of clauses.
    *
    * (*): MultiPartSubQuery is a structural sugar in the openCypher Xtext grammar
    *      not present in the original openCypher grammar
    */
  def multiPartSubQuery2Clauses(mpsq: oc.MultiPartSubQuery): Seq[oc.Clause] = {
      mpsq.getReadingClause.asScala ++ mpsq.getUpdatingClauses.asScala :+ mpsq.getWithPart
  }

  /** Builds the gplan for a single query built from several query parts.
    */
  def buildStatement(q: oc.SingleQuery): gplan.GNode = {
    // Compiled form of the query is the chain of the query parts.
    // The first query part will receive a dual object source there.
    // Accumulate tree built from successive query parts in result
    var result: gplan.GNode = gplan.Dual()

    // Do some checks on the clauses of the single query
    //FIXME: Validator.checkSingleQueryClauseSequence(clauses, ce.l)
    // A query part should have the form (MATCH*)((CREATE|DELETE)+ RETURN?|(WITH UNWIND?)|UNWIND|RETURN)

    q match {
      case spq: oc.SinglePartQuery => {
        val clauses: Seq[oc.Clause] = siglePartQuery2Clauses(spq)
        result = buildQueryPart(clauses, result)
      }
      case mpq: oc.MultiPartQuery => {
        for (queryPart <- mpq.getSubQueries.asScala) {
          result = buildQueryPart(multiPartSubQuery2Clauses(queryPart), result)
        }

        result = buildQueryPart(siglePartQuery2Clauses(mpq.getSinglePartQuery), result)
      }
    }

    result
  }

  def buildStatement(q: oc.CombinedQuery): gplan.GNode = {
    var result = buildStatement(q.getSingleQuery)

    for (u <- q.getUnion.asScala) {
      result = gplan.Union(u.isAll, result, buildStatement(u.getSingleQuery))
    }

    // FIXME: validator
    //		if (!Validator.checkIfUnionQueryColumnNamesMatch(result, ce.l)) {
    //			ce.l.unrecoverableError('''All sub queries of a UNION query must have the same column aliases.''')
    //		}

{'fraction_non_alphanumeric': 0.10366317069463445, 'fraction_numerical': 0.003343973248214014, 'mean_word_length': 3.4731475186947653, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 18, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7664247', 'n_tokens_mistral': 2178, 'n_tokens_neox': 2128, 'n_words': 481}