//
// Copyright 2019 Google LLC
//
// 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.
//

syntax = "proto2";

package zetasql;

option java_package = "com.google.zetasql";
option java_outer_classname = "ZetaSQLFunctions";

enum SignatureArgumentKind {
  // A specific concrete Type.  Each argument with ARG_TYPE_FIXED should include
  // an instance of the Type object to indicate the exact type to use.
  ARG_TYPE_FIXED = 0;

  // Templated type.  All arguments with this type must be the same type.
  // For example,
  //   IF <bool> THEN <T1> ELSE <T1> END -> <T1>
  ARG_TYPE_ANY_1 = 1;

  // Templated type.  All arguments with this type must be the same type.
  // For example,
  //   CASE <T1> WHEN <T1> THEN <T2>
  //             WHEN <T1> THEN <T2> ELSE <T2> END -> <T2>
  ARG_TYPE_ANY_2 = 2;

  // Templated array type.  All arguments with this type must be the same
  // type.  Additionally, all arguments with this type must be an array
  // whose element type matches arguments with ARG_TYPE_ANY_1 type.
  // For example,
  //   FIRST(<array<T1>>) -> <T1>
  ARG_ARRAY_TYPE_ANY_1 = 3;

  // Templated array type.  All arguments with this type must be the same
  // type.  Additionally, all arguments with this type must be an array
  // whose element type matches arguments with ARG_TYPE_ANY_2 type.
  // For example,
  //   LAST(<array<T2>>) -> <T2>
  ARG_ARRAY_TYPE_ANY_2 = 4;

  // Templated proto map type. This is an array of protos where the proto
  // is a map entry. It has a key field and a value field. This kind allows
  // inference of the key and value field types from the map field type, as
  // in this expression:
  //
  // ARG_PROTO_MAP_ANY[KEY(ARG_PROTO_MAP_KEY_ANY)] ->
  // ARG_PROTO_MAP_VALUE_ANY
  ARG_PROTO_MAP_ANY = 14;

  // The key type of a proto map that matches ARG_PROTO_MAP_ANY.
  ARG_PROTO_MAP_KEY_ANY = 15;

  // The value type of a proto map that matches ARG_PROTO_MAP_ANY.
  ARG_PROTO_MAP_VALUE_ANY = 16;

  // Templated proto type. All arguments with this type must be the same type.
  // e.g.:
  //   DEBUGSTRING(<proto>) -> <string>
  ARG_PROTO_ANY = 5;

  // Templated struct type. All arguments with this type must be the same type.
  // e.g.:
  //   DEBUGSTRING(<struct>) -> <string>
  ARG_STRUCT_ANY = 6;

  // Templated enum type. All arguments with this type must be the same type.
  // e.g.:
  //   ENUM_NAME(<enum>, 5) -> <string>
  ARG_ENUM_ANY = 7;

  // Arbitrary Type. Multiple arguments with this type do not need to be the
  // same type. This does not include relation arguments.
  ARG_TYPE_ARBITRARY = 8;

  // Relation type. This is only valid for table-valued functions (TVFs). This
  // specifies a relation of any number and types of columns. Multiple arguments
  // with this type do not necessarily represent the same relation.
  //
  // Background: each TVF may accept value or relation arguments. The signature
  // specifies whether each argument should be a value or a relation. For a
  // value argument, the signature may use one of the other
  // SignatureArgumentKinds in this list.
  //
  // For more information, please see table_valued_function.h.
  ARG_TYPE_RELATION = 9;

  // This is used for a non-existent return type for signatures that do not
  // return a value.  This can only be used as a return type, and only in
  // contexts where there is no return (e.g. Procedures, or signatures in
  // ResolvedDropFunctionStmt).
  ARG_TYPE_VOID = 10;

  // Model type. This is only valid for table-valued functions (TVFs). This
  // specifies a model for ML-related TVFs.
  // For more information, please see TVFModelArgument in
  // table_valued_function.h.
  ARG_TYPE_MODEL = 11;

  // Connection type. This is only valid for table-valued functions (TVFs). This
  // specifies a connection for EXTERNAL_QUERY TVF.
  // For more information, please see TVFConnectionArgument in
  // table_valued_function.h.
  ARG_TYPE_CONNECTION = 12;

  // Descriptor type. This is only valid for table-valued functions (TVFs). This
  // specifies a descriptor with a list of column names.
  // For more information, please see TVFDescriptorArgument in
  // table_valued_function.h.
  ARG_TYPE_DESCRIPTOR = 13;

  // Lambda type. This is only valid for lambda function arguments. This
  // specifies a lambda with a list of argument types and a body type.
  // For more information, please see ArgumentTypeLambda in
  // function_signature.h.
  ARG_TYPE_LAMBDA = 17;

  // Templated range type. All arguments with this type in the signature
  // must be of the same concrete type.
  // e.g.:
  //   RANGE(<date>, <date>) -> <date>
  ARG_RANGE_TYPE_ANY = 18;

  // Sequence type.
  ARG_TYPE_SEQUENCE = 22;

  __SignatureArgumentKind__switch_must_have_a_default__ = -1;
}

message FunctionEnums {
  enum ArgumentCardinality {
    REQUIRED = 0;
    REPEATED = 1;  // occurs 0 or more times
    OPTIONAL = 2;
  }

  // Function argument always has mode NOT_SET.
  // Procedure argument is in one of the 3 modes:
  // IN: argument is used only for input to the procedure. It is also the
  //     default mode for procedure argument if no mode is specified.
  // OUT: argument is used as output of the procedure.
  // INOUT: argument is used both for input to and output from the procedure.
  enum ProcedureArgumentMode {
    NOT_SET = 0;
    IN = 1;
    OUT = 2;
    INOUT = 3;
  }

  enum WindowOrderSupport {
    ORDER_UNSUPPORTED = 0;
    ORDER_OPTIONAL = 1;
    ORDER_REQUIRED = 2;
  }

  // A Function must have exactly one of the three modes: SCALAR, AGGREGATE,
  // and ANALYTIC. It is not possible to select a mode based on overload
  // resolution.
  // 1) A SCALAR function cannot specify support for the OVER clause in
  //    <function_options>.
  // 2) An AGGREGATE function can specify support for the OVER clause in
  //    <function_options>. For an AGGREGATE function with the support,
  //    it acts as an analytic function if an OVER clause follows the function
  //    call. Otherwise, it is treated as a regular aggregate function.
  // 3) An ANALYTIC function must specify support for the OVER clause in
  //    <function_options>. It cannot be used without OVER.
  enum Mode {
    SCALAR = 1;
    AGGREGATE = 2;
    ANALYTIC = 3;
  }

  // The volatility of a function determines how multiple executions of
  // a function are related, and whether we always get the same answer when
  // calling the function with the same input values.  Optimizers may use
  // this property when considering transformations like common subexpression
  // elimination.  Functions marked VOLATILE must be evaluated independently
  // each time time they occur.
  // This is based on postgres:
  // http://www.postgresql.org/docs/9.4/static/xfunc-volatility.html
  //
  // Note that volatility is a property of a Function, not an expression.
  // The function `+` is immutable, but in the expression "a + b", the
  // column references do not have a volatility property, and neither does the
  // expression.
  //
  // Functions like ANY_VALUE do not fit cleanly into this classification.
  // ANY_VALUE is not required to be deterministic, but is allowed to be.
  // Unlike RAND(), two calls to ANY_VALUE(x) are allowed to be combined by an
  // optimizer so the result is shared.  Such functions are marked IMMUTABLE.
  enum Volatility {
    IMMUTABLE = 0;  // Same answer for the same inputs.  e.g. 1+2
                    // Optimizers can always reuse results for computing
                    // this function on the same input values.
                    //
                    // Note that functions like ANY_VALUE and ARRAY_AGG are
                    // not fully deterministic since there are multiple legal
                    // answers, but we still mark these as IMMUTABLE because
                    // engines are allowed to reuse computed results.

    STABLE = 1;  // Same answer within same statement (for the same inputs).
                 // e.g. CURRENT_TIMESTAMP()
                 // Optimizers can always reuse results for computing
                 // this function on the same input values
                 // within the same statement.

    VOLATILE = 2;  // Each invocation is independent and may return a
                   // different value, or cause side-effects.
                   // e.g. RAND().
                   // Optimizers cannot combine multiple calls to this
                   // function or reuse results.  e.g. If RAND() is called
                   // twice, it must produce an output random value
                   // independently on each call.
  }

  // This is an enumeration of all types of table-valued functions that
  // ZetaSQL supports serializing and deserializing. It exists for use with
  // the TableValuedFunction::RegisterDeserializer method to associate each TVF
  // type with a callback to generate a new instance. Please see the comments
  // for that method for more information.
  enum TableValuedFunctionType {
    INVALID = 0;
    FIXED_OUTPUT_SCHEMA_TVF = 1;
    FORWARD_INPUT_SCHEMA_TO_OUTPUT_SCHEMA_TVF = 2;
    TEMPLATED_SQL_TVF = 3;
    FORWARD_INPUT_SCHEMA_TO_OUTPUT_SCHEMA_WITH_APPENDED_COLUMNS = 7;
  }

  // This is an enumeration for how a function argument's collation should
  // affect the function. The enum value can be used as a bit mask to check
  // whether AFFECTS_OPERATION or AFFECTS_PROPAGATION bit is set.
  enum ArgumentCollationMode {
    // The collation on the argument is ignored.
    AFFECTS_NONE = 0;
    // The bit for the collation on the argument only affects operation
    // collation.
    AFFECTS_OPERATION = 1;
    // The bit for the collation on the argument only affects collation
    // propagation.
    AFFECTS_PROPAGATION = 2;
    // The collation on the argument affects operation collation and propagation
    // collation. The enum value is intended to be AFFECTS_OPERATION |
    // AFFECTS_PROPAGATION.
    AFFECTS_OPERATION_AND_PROPAGATION = 3;
  }

  // Describes how an argument's name may be used when calling a function and
  // supplying a value for the argument.
  enum NamedArgumentKind {
    // Satisfies proto best practices.
    NAMED_ARGUMENT_KIND_UNSPECIFIED = 0;

    // The argument can be passed as a positional argument only.
    // We can add names to positional-only arguments for documentation purposes,
    // including error messages, but they cannot be used in SQL.
    POSITIONAL_ONLY = 1;

    // The argument can be passed as either a positional or named argument.
    POSITIONAL_OR_NAMED = 2;

    // The argument can be passed as a named argument only.
    NAMED_ONLY = 3;
  }
}
