// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The ASF licenses this file
// to you 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.

//go:build go1.18

package compute

import (
	

	
	
	
)

var (
	andDoc = FunctionDoc{
		Summary:     "Logical 'and' boolean values",
		Description: "When a null is encountered in either input, a null is output.\nFor a different null behavior, see function 'and_kleene'",
		ArgNames:    []string{"x", "y"},
	}
	andNotDoc = FunctionDoc{
		Summary:     "Logical 'and not' boolean values",
		Description: "When a null is encountered in either input, a null is output.\nFor a different null behavior, see function 'and_not_kleene'",
		ArgNames:    []string{"x", "y"},
	}
	orDoc = FunctionDoc{
		Summary:     "Logical 'or' boolean values",
		Description: "When a null is encountered in either input, a null is output.\nFor a different null behavior, see function 'or_kleene'",
		ArgNames:    []string{"x", "y"},
	}
	xorDoc = FunctionDoc{
		Summary:     "Logical 'xor' boolean values",
		Description: "When a null is encountered in either input, a null is output.",
		ArgNames:    []string{"x", "y"},
	}
	andKleeneDoc = FunctionDoc{
		Summary: "Logical 'and' boolean values (Kleene logic)",
		Description: `This function behaves as follows with nulls:
		
		- true and null = null
		- null and true = null
		- false and null = false
		- null and false = false
		- null and null = null
		
		In other words, in this context, a null value really means "unknown"
		and an unknown value "and" false is always false.
		For a different null behavior, see function "and".`,
		ArgNames: []string{"x", "y"},
	}
	andNotKleeneDoc = FunctionDoc{
		Summary: "Logical 'and_not' boolean values (Kleene logic)",
		Description: `This function behaves as follows with nulls:
		
		- true and not null = null
		- null and not false = null
		- false and not null = false
		- null and not true = false
		- null and not null = null
		
		In other words, in this context, a null value really means "unknown"
		and an unknown value "and not" true is always false, as is false
		"and not" an unknown value.
		For a different null behavior, see function "and_not".`,
		ArgNames: []string{"x", "y"},
	}
	orKleeneDoc = FunctionDoc{
		Summary: "Logical 'or' boolean values (Kleene logic)",
		Description: `This function behaves as follows with nulls:
		
		- true or null = true
		- null or true = true
		- false or null = null
		- null or false = null
		- null or null = null
		
		In other words, in this context, a null value really means "unknown"
		and an unknown value "or" true is always true.
		For a different null behavior, see function "and".`,
		ArgNames: []string{"x", "y"},
	}
	notDoc = FunctionDoc{
		Summary:     "Logical 'not' boolean values",
		Description: "Negates the input boolean value",
		ArgNames:    []string{"x"},
	}
)

func makeFunction( FunctionRegistry,  string,  int,  exec.ArrayKernelExec,  FunctionDoc,  exec.NullHandling) {
	 := NewScalarFunction(, Arity{NArgs: }, )

	 := make([]exec.InputType, )
	for  := range  {
		[] = exec.NewExactInput(arrow.FixedWidthTypes.Boolean)
	}

	 := exec.NewScalarKernel(, exec.NewOutputType(arrow.FixedWidthTypes.Boolean), , nil)
	.NullHandling = 

	if  := .AddKernel();  != nil {
		panic()
	}

	if !.AddFunction(, false) {
		panic(fmt.Errorf("function '%s' already exists", ))
	}
}

func ( FunctionRegistry) {
	makeFunction(, "and", 2, kernels.SimpleBinary[kernels.AndOpKernel],
		andDoc, exec.NullIntersection)
	makeFunction(, "and_not", 2, kernels.SimpleBinary[kernels.AndNotOpKernel],
		andNotDoc, exec.NullIntersection)
	makeFunction(, "or", 2, kernels.SimpleBinary[kernels.OrOpKernel],
		orDoc, exec.NullIntersection)
	makeFunction(, "xor", 2, kernels.SimpleBinary[kernels.XorOpKernel],
		xorDoc, exec.NullIntersection)
	makeFunction(, "and_kleene", 2, kernels.SimpleBinary[kernels.KleeneAndOpKernel],
		andKleeneDoc, exec.NullComputedPrealloc)
	makeFunction(, "and_not_kleene", 2, kernels.SimpleBinary[kernels.KleeneAndNotOpKernel],
		andNotKleeneDoc, exec.NullComputedPrealloc)
	makeFunction(, "or_kleene", 2, kernels.SimpleBinary[kernels.KleeneOrOpKernel],
		orKleeneDoc, exec.NullComputedPrealloc)
	makeFunction(, "not", 1, kernels.NotExecKernel, notDoc,
		exec.NullComputedNoPrealloc)
}