All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.opencypher.v9_0.expressions.functions.Function.scala Maven / Gradle / Ivy

The newest version!
/*
 * Copyright (c) Neo4j Sweden AB (http://neo4j.com)
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.opencypher.v9_0.expressions.functions

import org.opencypher.v9_0.expressions.Expression
import org.opencypher.v9_0.expressions.FunctionInvocation
import org.opencypher.v9_0.expressions.FunctionName
import org.opencypher.v9_0.expressions.FunctionTypeSignature
import org.opencypher.v9_0.expressions.TypeSignatures
import org.opencypher.v9_0.util.InputPosition

object Category extends Enumeration {
  val NUMERIC = "Numeric"
  val TRIGONOMETRIC = "Trigonometric"
  val PREDICATE = "Predicate"
  val AGGREGATING = "Aggregating"
  val SCALAR = "Scalar"
  val TEMPORAL = "Temporal"
  val LOGARITHMIC = "Logarithmic"
  val LIST = "List"
  val STRING = "String"
  val SPATIAL = "Spatial"
}

object Function {
  private val knownFunctions: Seq[Function] = Vector(
    Abs,
    Acos,
    Asin,
    Atan,
    Atan2,
    Avg,
    Ceil,
    Coalesce,
    Collect,
    Ceil,
    Cos,
    Cot,
    Count,
    Degrees,
    Distance,
    E,
    EndNode,
    Exists,
    Exp,
    File,
    Floor,
    Haversin,
    Head,
    Id,
    IsEmpty,
    Labels,
    Last,
    Left,
    Length,
    Linenumber,
    Log,
    Log10,
    LTrim,
    Max,
    Min,
    Nodes,
    Pi,
    PercentileCont,
    PercentileDisc,
    Point,
    Keys,
    Radians,
    Rand,
    RandomUUID,
    Range,
    Reduce,
    Relationships,
    Replace,
    Reverse,
    Right,
    Round,
    RTrim,
    Sign,
    Sin,
    Size,
    Sqrt,
    Split,
    StartNode,
    StdDev,
    StdDevP,
    Substring,
    Sum,
    Tail,
    Tan,
    ToBoolean,
    ToFloat,
    ToInteger,
    ToLower,
    ToString,
    ToUpper,
    Properties,
    Trim,
    Type
  )

  lazy val lookup: Map[String, Function] = knownFunctions.map { f => (f.name.toLowerCase, f) }.toMap

  lazy val functionInfo: List[FunctionTypeSignature] = {
    lookup.values.flatMap {
      f: Function =>
        f.signatures.flatMap {
          case signature: FunctionTypeSignature if !signature.deprecated => Some(signature)
          case signature: FunctionTypeSignature if signature.deprecated => None
          case problem =>
            throw new IllegalStateException("Did not expect the following at this point: " + problem)
        }
    }.toList
  }
}

abstract case class FunctionInfo(f: FunctionWithName) {
  def getFunctionName: String = f.name

  def isAggregationFunction: Boolean = f match {
    case _: AggregatingFunction => true
    case _ => false
  }

  def getDescription: String

  def getCategory: String

  def getSignature: String

  override def toString: String = getFunctionName + " || " + getSignature + " || " + getDescription + " || " + isAggregationFunction
}

abstract class Function extends FunctionWithName with TypeSignatures {
  private val functionName = asFunctionName(InputPosition.NONE)

  def asFunctionName(implicit position: InputPosition): FunctionName = FunctionName(name)(position)

  def asInvocation(argument: Expression, distinct: Boolean = false)(implicit position: InputPosition): FunctionInvocation =
    FunctionInvocation(asFunctionName, distinct = distinct, IndexedSeq(argument))(position)

  def asInvocation(lhs: Expression, rhs: Expression)(implicit position: InputPosition): FunctionInvocation =
    FunctionInvocation(asFunctionName, distinct = false, IndexedSeq(lhs, rhs))(position)

  // Default apply and unapply methods which are valid for functions taking exactly one argument
  def apply(arg: Expression)(pos: InputPosition): FunctionInvocation =
    FunctionInvocation(asFunctionName(pos), arg)(pos)

  def unapply(arg: Expression): Option[Expression] =
    arg match {
      case FunctionInvocation(_, `functionName`, _, args) => Some(args.head)
      case _ => None
    }
}

trait FunctionWithName {
  def name: String
}

abstract class AggregatingFunction extends Function




© 2015 - 2025 Weber Informatics LLC | Privacy Policy