blob: aec4efce7e4964408b02034922f719ed1aaa1b47 [file] [log] [blame]
/**********************************************************************
// @@@ START COPYRIGHT @@@
//
// 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.
//
// @@@ END COPYRIGHT @@@
**********************************************************************/
/* -*-C++-*-
*****************************************************************************
*
* File: <file>
* Description:
*
*
* Created: 7/10/95
* Language: C++
*
*
*
*
*****************************************************************************
*/
#include "Platform.h"
#include "exp_stdh.h"
#include "exp_clause_derived.h"
#include "exp_datetime.h"
#include "unicode_char_set.h"
#include "wstr.h"
#include "ex_globals.h"
ex_expr::exp_return_type ex_comp_clause::processNulls(char *op_data[],
CollHeap *heap,
ComDiagsArea **diagsArea)
{
if (isSpecialNulls())
{
// special nulls. Nulls are values.
// Null = Null, non-null-value < NULL, etc.
short left_is_null = 0;
short right_is_null = 0;
if (getOperand(1)->getNullFlag() && (!op_data[1]))
left_is_null = -1;
if (getOperand(2)->getNullFlag() && (!op_data[2]))
right_is_null = -1;
Lng32 result = 0;
if ((left_is_null) || (right_is_null))
{
switch (getOperType())
{
case ITM_EQUAL:
result = (left_is_null && right_is_null ? -1 : 0);
break;
case ITM_NOT_EQUAL:
result = (left_is_null && right_is_null ? 0 : -1);
break;
case ITM_GREATER:
result = (right_is_null ? 0 : -1);
break;
case ITM_LESS:
result = (left_is_null ? 0 : -1);
break;
case ITM_GREATER_EQ:
result = (left_is_null ? -1 : 0);
break;
case ITM_LESS_EQ:
result = (right_is_null ? -1 : 0);
break;
}
if (result)
{
// the actual result of this operation is pointed to
// by op_data[2 * MAX_OPERANDS].
*(Lng32 *)op_data[2 * MAX_OPERANDS] = 1; // result is TRUE
}
else
{
*(Lng32 *)op_data[2 * MAX_OPERANDS] = 0; // result is FALSE
if ((getRollupColumnNum() >= 0) &&
(getExeGlobals()))
{
getExeGlobals()->setRollupColumnNum(getRollupColumnNum());
}
}
return ex_expr::EXPR_NULL;
} // one of the operands is a null value.
} // nulls are to be treated as values
for (short i = 1; i < getNumOperands(); i++)
{
// if value is missing,
// then move boolean unknown value to result and return.
if (getOperand(i)->getNullFlag() && (!op_data[i])) // missing value
{
// move null value to result.
*(Lng32 *)op_data[2 * MAX_OPERANDS] = -1;
return ex_expr::EXPR_NULL;
}
}
return ex_expr::EXPR_OK;
}
ex_expr::exp_return_type
ex_comp_clause::processResult(Int32 compare_code, Lng32* result,
CollHeap *heap,
ComDiagsArea** diagsArea)
{
*result = 0;
switch (getOperType())
{
case ITM_EQUAL:
if (compare_code == 0)
*result = 1;
break;
case ITM_NOT_EQUAL:
if (compare_code != 0)
*result = 1;
break;
case ITM_LESS:
if (compare_code < 0)
*result = 1;
break;
case ITM_LESS_EQ:
if (compare_code <= 0)
*result = 1;
break;
case ITM_GREATER:
if (compare_code > 0)
*result = 1;
break;
case ITM_GREATER_EQ:
if (compare_code >= 0)
*result = 1;
break;
default:
ExRaiseSqlError(heap, diagsArea, EXE_INTERNAL_ERROR);
return ex_expr::EXPR_ERROR;
break;
}
return ex_expr::EXPR_OK;
}
/////////////////////////////////////////////////////////////////
// Compares operand 1 and operand 2. Moves boolean result to
// operand 0. Result is a boolean datatype.
// Result values: 1, TRUE. 0, FALSE.
// -1, NULL (but this shouldn't happen here.
// Nulls have already been processed
// before coming here).
////////////////////////////////////////////////////////////////
ex_expr::exp_return_type ex_comp_clause::eval(char *op_data[],
CollHeap *heap,
ComDiagsArea** diagsArea)
{
ex_expr::exp_return_type retcode = ex_expr::EXPR_OK;
switch (getInstruction())
{
// EQUAL opcode
case EQ_BIN8S_BIN8S:
*(Lng32 *)op_data[0] = (*(Int8 *)op_data[1] == *(Int8 *)op_data[2]);
break;
case EQ_BIN8U_BIN8U:
*(Lng32 *)op_data[0] = (*(UInt8 *)op_data[1] == *(UInt8 *)op_data[2]);
break;
case EQ_BIN16S_BIN16S:
*(Lng32 *)op_data[0] = (*(short *)op_data[1] == *(short *)op_data[2]);
break;
case EQ_BIN16S_BIN32S:
*(Lng32 *)op_data[0] = (*(short *)op_data[1] == *(Lng32 *)op_data[2]);
break;
case EQ_BIN16S_BIN16U:
*(Lng32 *)op_data[0] = (*(short *)op_data[1] == *(unsigned short *)op_data[2]);
break;
case EQ_BIN16S_BIN32U:
*(Lng32 *)op_data[0] = ((ULng32)*(short *)op_data[1] == *(ULng32 *)op_data[2]);
break;
case EQ_BIN16U_BIN16S:
*(Lng32 *)op_data[0] = (*(unsigned short *)op_data[1] == *(short *)op_data[2]);
break;
case EQ_BIN16U_BIN32S:
*(Lng32 *)op_data[0] = (*(unsigned short *)op_data[1] == *(Lng32 *)op_data[2]);
break;
case EQ_BIN16U_BIN16U:
*(Lng32 *)op_data[0] = (*(unsigned short *)op_data[1] == *(unsigned short *)op_data[2]);
break;
case EQ_BIN16U_BIN32U:
*(Lng32 *)op_data[0] = (*(unsigned short *)op_data[1] == *(ULng32 *)op_data[2]);
break;
case EQ_BIN32S_BIN16S:
*(Lng32 *)op_data[0] = (*(Lng32 *)op_data[1] == *(short *)op_data[2]);
break;
case EQ_BIN32S_BIN32S:
*(Lng32 *)op_data[0] = (*(Lng32 *)op_data[1] == *(Lng32 *)op_data[2]);
break;
case EQ_BIN32S_BIN16U:
*(Lng32 *)op_data[0] = (*(Lng32 *)op_data[1] == *(unsigned short *)op_data[2]);
break;
case EQ_BIN32S_BIN32U:
*(Lng32 *)op_data[0] = ((ULng32)*(Lng32 *)op_data[1] == *(ULng32 *)op_data[2]);
break;
case EQ_BIN32U_BIN16S:
*(Lng32 *)op_data[0] = (*(ULng32 *)op_data[1] == (ULng32)*(short *)op_data[2]);
break;
case EQ_BIN32U_BIN32S:
*(Lng32 *)op_data[0] = (*(ULng32 *)op_data[1] == (ULng32)*(Lng32 *)op_data[2]);
break;
case EQ_BIN32U_BIN16U:
*(Lng32 *)op_data[0] = (*(ULng32 *)op_data[1] == *(unsigned short *)op_data[2]);
break;
case EQ_BIN32U_BIN32U:
*(Lng32 *)op_data[0] = (*(ULng32 *)op_data[1] == *(ULng32 *)op_data[2]);
break;
case EQ_BIN64S_BIN64S:
*(Lng32 *)op_data[0] = (*(Int64 *)op_data[1] == *(Int64 *)op_data[2]);
break;
case EQ_BIN64U_BIN64U:
*(Lng32 *)op_data[0] = (*(UInt64 *)op_data[1] == *(UInt64 *)op_data[2]);
break;
case EQ_BIN64U_BIN64S:
*(Lng32 *)op_data[0] = (*(UInt64 *)op_data[1] == *(Int64 *)op_data[2]);
break;
case EQ_BIN64S_BIN64U:
*(Lng32 *)op_data[0] = (*(Int64 *)op_data[1] == *(UInt64 *)op_data[2]);
break;
case EQ_DECU_DECU:
case EQ_DECS_DECS:
case EQ_ASCII_F_F:
case EQ_UNICODE_F_F: // 11/3/97 added for Unicode support
if (str_cmp(op_data[1], op_data[2], (Int32)getOperand(1)->getLength()) == 0)
*(Lng32 *)op_data[0] = 1;
else
*(Lng32 *)op_data[0] = 0;
break;
case EQ_FLOAT32_FLOAT32:
*(Lng32 *)op_data[0] = (*(float *)op_data[1] == *(float *)op_data[2]);
break;
case EQ_FLOAT64_FLOAT64:
*(Lng32 *)op_data[0] = (*(double *)op_data[1] == *(double *)op_data[2]);
break;
case EQ_DATETIME_DATETIME:
if (((ExpDatetime *) getOperand(1))->compDatetimes(op_data[1],
op_data[2]) == 0)
*(Lng32 *)op_data[0] = 1;
else
*(Lng32 *)op_data[0] = 0;
break;
// NOT EQUAL operator
case NE_BIN8S_BIN8S:
*(Lng32 *)op_data[0] = (*(Int8 *)op_data[1] != *(Int8 *)op_data[2]);
break;
case NE_BIN8U_BIN8U:
*(Lng32 *)op_data[0] = (*(UInt8 *)op_data[1] != *(UInt8 *)op_data[2]);
break;
case NE_BIN16S_BIN16S:
*(Lng32 *)op_data[0] = (*(short *)op_data[1] != *(short *)op_data[2]);
break;
case NE_BIN16S_BIN32S:
*(Lng32 *)op_data[0] = (*(short *)op_data[1] != *(Lng32 *)op_data[2]);
break;
case NE_BIN16S_BIN16U:
*(Lng32 *)op_data[0] = (*(short *)op_data[1] != *(unsigned short *)op_data[2]);
break;
case NE_BIN16S_BIN32U:
*(Lng32 *)op_data[0] = ((ULng32)*(short *)op_data[1] != *(ULng32 *)op_data[2]);
break;
case NE_BIN16U_BIN16S:
*(Lng32 *)op_data[0] = (*(unsigned short *)op_data[1] != *(short *)op_data[2]);
break;
case NE_BIN16U_BIN32S:
*(Lng32 *)op_data[0] = (*(unsigned short *)op_data[1] != *(Lng32 *)op_data[2]);
break;
case NE_BIN16U_BIN16U:
*(Lng32 *)op_data[0] = (*(unsigned short *)op_data[1] != *(unsigned short *)op_data[2]);
break;
case NE_BIN16U_BIN32U:
*(Lng32 *)op_data[0] = (*(unsigned short *)op_data[1] != *(ULng32 *)op_data[2]);
break;
case NE_BIN32S_BIN16S:
*(Lng32 *)op_data[0] = (*(Lng32 *)op_data[1] != *(short *)op_data[2]);
break;
case NE_BIN32S_BIN32S:
*(Lng32 *)op_data[0] = (*(Lng32 *)op_data[1] != *(Lng32 *)op_data[2]);
break;
case NE_BIN32S_BIN16U:
*(Lng32 *)op_data[0] = (*(Lng32 *)op_data[1] != *(unsigned short *)op_data[2]);
break;
case NE_BIN32S_BIN32U:
*(Lng32 *)op_data[0] = ((ULng32)*(Lng32 *)op_data[1] != *(ULng32 *)op_data[2]);
break;
case NE_BIN32U_BIN16S:
*(Lng32 *)op_data[0] = (*(ULng32 *)op_data[1] != (ULng32)*(short *)op_data[2]);
break;
case NE_BIN32U_BIN32S:
*(Lng32 *)op_data[0] = (*(ULng32 *)op_data[1] != (ULng32)*(Lng32 *)op_data[2]);
break;
case NE_BIN32U_BIN16U:
*(Lng32 *)op_data[0] = (*(ULng32 *)op_data[1] != *(unsigned short *)op_data[2]);
break;
case NE_BIN32U_BIN32U:
*(Lng32 *)op_data[0] = (*(ULng32 *)op_data[1] != *(ULng32 *)op_data[2]);
break;
case NE_BIN64S_BIN64S:
*(Lng32 *)op_data[0] = (*(Int64 *)op_data[1] != *(Int64 *)op_data[2]);
break;
case NE_BIN64U_BIN64U:
*(Lng32 *)op_data[0] = (*(UInt64 *)op_data[1] != *(UInt64 *)op_data[2]);
break;
case NE_BIN64U_BIN64S:
*(Lng32 *)op_data[0] = (*(UInt64 *)op_data[1] != *(Int64 *)op_data[2]);
break;
case NE_BIN64S_BIN64U:
*(Lng32 *)op_data[0] = (*(Int64 *)op_data[1] != *(UInt64 *)op_data[2]);
break;
case NE_DECU_DECU:
case NE_DECS_DECS:
case NE_ASCII_F_F:
if (str_cmp(op_data[1], op_data[2], (Int32)getOperand(1)->getLength()) != 0)
*(Lng32 *)op_data[0] = 1;
else
*(Lng32 *)op_data[0] = 0;
break;
case NE_UNICODE_F_F: // 11/3/97: Added for Unicode support
if (wc_str_cmp((NAWchar*)op_data[1], (NAWchar*)op_data[2],
(Int32)getOperand(1)->getLength() >> 1) != 0)
*(Lng32 *)op_data[0] = 1;
else
*(Lng32 *)op_data[0] = 0;
break;
case NE_FLOAT32_FLOAT32:
*(Lng32 *)op_data[0] = (*(float *)op_data[1] != *(float *)op_data[2]);
break;
case NE_FLOAT64_FLOAT64:
*(Lng32 *)op_data[0] = (*(double *)op_data[1] != *(double *)op_data[2]);
break;
case NE_DATETIME_DATETIME:
if (((ExpDatetime *) getOperand(1))->compDatetimes(op_data[1],
op_data[2]) != 0)
*(Lng32 *)op_data[0] = 1;
else
*(Lng32 *)op_data[0] = 0;
break;
// LESS THAN opcode
case LT_BIN8S_BIN8S:
*(Lng32 *)op_data[0] = (*(Int8 *)op_data[1] < *(Int8 *)op_data[2]);
break;
case LT_BIN8U_BIN8U:
*(Lng32 *)op_data[0] = (*(UInt8 *)op_data[1] < *(UInt8 *)op_data[2]);
break;
case LT_BIN16S_BIN16S:
*(Lng32 *)op_data[0] = (*(short *)op_data[1] < *(short *)op_data[2]);
break;
case LT_BIN16S_BIN32S:
*(Lng32 *)op_data[0] = (*(short *)op_data[1] < *(Lng32 *)op_data[2]);
break;
case LT_BIN16S_BIN16U:
*(Lng32 *)op_data[0] = (*(short *)op_data[1] < *(unsigned short *)op_data[2]);
break;
case LT_BIN16S_BIN32U:
*(Lng32 *)op_data[0] = ((Int64)*(short *)op_data[1] < (Int64)*(ULng32 *)op_data[2]);
break;
case LT_BIN16U_BIN16S:
*(Lng32 *)op_data[0] = (*(unsigned short *)op_data[1] < *(short *)op_data[2]);
break;
case LT_BIN16U_BIN32S:
*(Lng32 *)op_data[0] = (*(unsigned short *)op_data[1] < *(Lng32 *)op_data[2]);
break;
case LT_BIN16U_BIN16U:
*(Lng32 *)op_data[0] = (*(unsigned short *)op_data[1] < *(unsigned short *)op_data[2]);
break;
case LT_BIN16U_BIN32U:
*(Lng32 *)op_data[0] = (*(unsigned short *)op_data[1] < *(ULng32 *)op_data[2]);
break;
case LT_BIN32S_BIN16S:
*(Lng32 *)op_data[0] = (*(Lng32 *)op_data[1] < *(short *)op_data[2]);
break;
case LT_BIN32S_BIN32S:
*(Lng32 *)op_data[0] = (*(Lng32 *)op_data[1] < *(Lng32 *)op_data[2]);
break;
case LT_BIN32S_BIN16U:
*(Lng32 *)op_data[0] = (*(Lng32 *)op_data[1] < *(unsigned short *)op_data[2]);
break;
case LT_BIN32S_BIN32U:
*(Lng32 *)op_data[0] = ((Int64)*(Lng32 *)op_data[1] < (Int64)*(ULng32 *)op_data[2]);
break;
case LT_BIN32U_BIN16S:
*(Lng32 *)op_data[0] = ((Int64)*(ULng32 *)op_data[1] < *(short *)op_data[2]);
break;
case LT_BIN32U_BIN32S:
*(Lng32 *)op_data[0] = ((Int64)*(ULng32 *)op_data[1] < (Int64)*(Lng32 *)op_data[2]);
break;
case LT_BIN32U_BIN16U:
*(Lng32 *)op_data[0] = (*(ULng32 *)op_data[1] < *(unsigned short *)op_data[2]);
break;
case LT_BIN32U_BIN32U:
*(Lng32 *)op_data[0] = (*(ULng32 *)op_data[1] < *(ULng32 *)op_data[2]);
break;
case LT_BIN64S_BIN64S:
*(Lng32 *)op_data[0] = (*(Int64 *)op_data[1] < *(Int64 *)op_data[2]);
break;
case LT_BIN64U_BIN64U:
*(Lng32 *)op_data[0] = (*(UInt64 *)op_data[1] < *(UInt64 *)op_data[2]);
break;
case LT_BIN64U_BIN64S:
*(Lng32 *)op_data[0] =
((*(Int64*)op_data[2] < 0) ? 0 :
(*(UInt64 *)op_data[1] < *(Int64 *)op_data[2]));
break;
case LT_BIN64S_BIN64U:
*(Lng32 *)op_data[0] =
((*(Int64*)op_data[1] < 0) ? 1 :
(*(Int64 *)op_data[1] < *(UInt64 *)op_data[2]));
break;
case LT_DECS_DECS:
{
if ((op_data[1][0] & 0200) == 0)
{
// first operand is positive
if ((op_data[2][0] & 0200) == 0)
{
// second operand is positive
if (str_cmp(op_data[1], op_data[2],
(Int32)getOperand(1)->getLength()) < 0) // l < r
*(Lng32 *)op_data[0] = 1;
else
*(Lng32 *)op_data[0] = 0;
}
else
{
// second operand is negative
*(Lng32 *)op_data[0] = 0; // +ve not < -ve
}
}
else
{
// first operand is negative
if ((op_data[2][0] & 0200) == 0)
{
// second operand is positive
*(Lng32 *)op_data[0] = 1; // -ve negative always < +ve
}
else
{
// second operand is negative
if (str_cmp(op_data[1], op_data[2],
(Int32)getOperand(1)->getLength()) <= 0) // l <= r
*(Lng32 *)op_data[0] = 0;
else
*(Lng32 *)op_data[0] = 1;
}
} // first operand is negative
}
break;
case LT_DECU_DECU:
case LT_ASCII_F_F:
if (str_cmp(op_data[1], op_data[2], (Int32)getOperand(1)->getLength()) < 0)
*(Lng32 *)op_data[0] = 1;
else
*(Lng32 *)op_data[0] = 0;
break;
case LT_UNICODE_F_F: // 11/5/97: added for Unicode support
if (wc_str_cmp((NAWchar*)op_data[1], (NAWchar*)op_data[2],
(Int32)getOperand(1)->getLength() >> 1) < 0)
*(Lng32 *)op_data[0] = 1;
else
*(Lng32 *)op_data[0] = 0;
break;
case LT_FLOAT32_FLOAT32:
*(Lng32 *)op_data[0] = (*(float *)op_data[1] < *(float *)op_data[2]);
break;
case LT_FLOAT64_FLOAT64:
*(Lng32 *)op_data[0] = (*(double *)op_data[1] < *(double *)op_data[2]);
break;
case LT_DATETIME_DATETIME:
if (((ExpDatetime *) getOperand(1))->compDatetimes(op_data[1],
op_data[2]) < 0)
*(Lng32 *)op_data[0] = 1;
else
*(Lng32 *)op_data[0] = 0;
break;
// LESS THAN OR EQUAL TO opcode
case LE_BIN8S_BIN8S:
*(Lng32 *)op_data[0] = (*(Int8 *)op_data[1] <= *(Int8 *)op_data[2]);
break;
case LE_BIN8U_BIN8U:
*(Lng32 *)op_data[0] = (*(UInt8 *)op_data[1] <= *(UInt8 *)op_data[2]);
break;
case LE_BIN16S_BIN16S:
*(Lng32 *)op_data[0] = (*(short *)op_data[1] <= *(short *)op_data[2]);
break;
case LE_BIN16S_BIN32S:
*(Lng32 *)op_data[0] = (*(short *)op_data[1] <= *(Lng32 *)op_data[2]);
break;
case LE_BIN16S_BIN16U:
*(Lng32 *)op_data[0] = (*(short *)op_data[1] <= *(unsigned short *)op_data[2]);
break;
case LE_BIN16S_BIN32U:
*(Lng32 *)op_data[0] = (*(short *)op_data[1] <= (Int64)*(ULng32 *)op_data[2]);
break;
case LE_BIN16U_BIN16S:
*(Lng32 *)op_data[0] = (*(unsigned short *)op_data[1] <= *(short *)op_data[2]);
break;
case LE_BIN16U_BIN32S:
*(Lng32 *)op_data[0] = (*(unsigned short *)op_data[1] <= *(Lng32 *)op_data[2]);
break;
case LE_BIN16U_BIN16U:
*(Lng32 *)op_data[0] = (*(unsigned short *)op_data[1] <= *(unsigned short *)op_data[2]);
break;
case LE_BIN16U_BIN32U:
*(Lng32 *)op_data[0] = (*(unsigned short *)op_data[1] <= *(ULng32 *)op_data[2]);
break;
case LE_BIN32S_BIN16S:
*(Lng32 *)op_data[0] = (*(Lng32 *)op_data[1] <= *(short *)op_data[2]);
break;
case LE_BIN32S_BIN32S:
*(Lng32 *)op_data[0] = (*(Lng32 *)op_data[1] <= *(Lng32 *)op_data[2]);
break;
case LE_BIN32S_BIN16U:
*(Lng32 *)op_data[0] = (*(Lng32 *)op_data[1] <= *(unsigned short *)op_data[2]);
break;
case LE_BIN32S_BIN32U:
*(Lng32 *)op_data[0] = ((Int64)*(Lng32 *)op_data[1] <= (Int64)*(ULng32 *)op_data[2]);
break;
case LE_BIN32U_BIN16S:
*(Lng32 *)op_data[0] = ((Int64)*(ULng32 *)op_data[1] <= *(short *)op_data[2]);
break;
case LE_BIN32U_BIN32S:
*(Lng32 *)op_data[0] = ((Int64)*(ULng32 *)op_data[1] <= (Int64)*(Lng32 *)op_data[2]);
break;
case LE_BIN32U_BIN16U:
*(Lng32 *)op_data[0] = (*(ULng32 *)op_data[1] <= *(unsigned short *)op_data[2]);
break;
case LE_BIN32U_BIN32U:
*(Lng32 *)op_data[0] = (*(ULng32 *)op_data[1] <= *(ULng32 *)op_data[2]);
break;
case LE_BIN64S_BIN64S:
*(Lng32 *)op_data[0] = (*(Int64 *)op_data[1] <= *(Int64 *)op_data[2]);
break;
case LE_BIN64U_BIN64U:
*(Lng32 *)op_data[0] = (*(UInt64 *)op_data[1] <= *(UInt64 *)op_data[2]);
break;
case LE_BIN64U_BIN64S:
*(Lng32 *)op_data[0] =
((*(Int64*)op_data[2] < 0) ? 0 :
(*(UInt64 *)op_data[1] <= *(Int64 *)op_data[2]));
break;
case LE_BIN64S_BIN64U:
*(Lng32 *)op_data[0] =
((*(Int64*)op_data[1] < 0) ? 1 :
(*(Int64 *)op_data[1] <= *(UInt64 *)op_data[2]));
break;
case LE_DECS_DECS:
{
if ((op_data[1][0] & 0200) == 0)
{
// first operand is positive
if ((op_data[2][0] & 0200) == 0)
{
// second operand is positive
if (str_cmp(op_data[1], op_data[2],
(Int32)getOperand(1)->getLength()) <= 0) // l <= r
*(Lng32 *)op_data[0] = 1;
else
*(Lng32 *)op_data[0] = 0;
}
else
{
// second operand is negative
*(Lng32 *)op_data[0] = 0; // +ve not < -ve
}
}
else
{
// first operand is negative
if ((op_data[2][0] & 0200) == 0)
{
// second operand is positive
*(Lng32 *)op_data[0] = 1; // -ve negative always < +ve
}
else
{
// second operand is negative
if (str_cmp(op_data[1], op_data[2],
(Int32)getOperand(1)->getLength()) < 0) // l < r
*(Lng32 *)op_data[0] = 0;
else
*(Lng32 *)op_data[0] = 1;
}
} // first operand is negative
}
break;
case LE_DECU_DECU:
case LE_ASCII_F_F:
if (str_cmp(op_data[1], op_data[2], (Int32)getOperand(1)->getLength()) <= 0)
*(Lng32 *)op_data[0] = 1;
else
*(Lng32 *)op_data[0] = 0;
break;
case LE_UNICODE_F_F: // 11/5/97: added for Unicode support
if (wc_str_cmp((NAWchar*)op_data[1], (NAWchar*)op_data[2],
(Int32)getOperand(1)->getLength() >> 1) <= 0)
*(Lng32 *)op_data[0] = 1;
else
*(Lng32 *)op_data[0] = 0;
break;
case LE_FLOAT32_FLOAT32:
*(Lng32 *)op_data[0] = (*(float *)op_data[1] <= *(float *)op_data[2]);
break;
case LE_FLOAT64_FLOAT64:
*(Lng32 *)op_data[0] = (*(double *)op_data[1] <= *(double *)op_data[2]);
break;
case LE_DATETIME_DATETIME:
if (((ExpDatetime *) getOperand(1))->compDatetimes(op_data[1],
op_data[2]) <= 0)
*(Lng32 *)op_data[0] = 1;
else
*(Lng32 *)op_data[0] = 0;
break;
// GREATER THAN opcode
case GT_BIN8S_BIN8S:
*(Lng32 *)op_data[0] = (*(Int8 *)op_data[1] > *(Int8 *)op_data[2]);
break;
case GT_BIN8U_BIN8U:
*(Lng32 *)op_data[0] = (*(UInt8 *)op_data[1] > *(UInt8 *)op_data[2]);
break;
case GT_BIN16S_BIN16S:
*(Lng32 *)op_data[0] = (*(short *)op_data[1] > *(short *)op_data[2]);
break;
case GT_BIN16S_BIN32S:
*(Lng32 *)op_data[0] = (*(short *)op_data[1] > *(Lng32 *)op_data[2]);
break;
case GT_BIN16S_BIN16U:
*(Lng32 *)op_data[0] = (*(short *)op_data[1] > *(unsigned short *)op_data[2]);
break;
case GT_BIN16S_BIN32U:
*(Lng32 *)op_data[0] = (*(short *)op_data[1] > (Int64)*(ULng32 *)op_data[2]);
break;
case GT_BIN16U_BIN16S:
*(Lng32 *)op_data[0] = (*(unsigned short *)op_data[1] > *(short *)op_data[2]);
break;
case GT_BIN16U_BIN32S:
*(Lng32 *)op_data[0] = (*(unsigned short *)op_data[1] > *(Lng32 *)op_data[2]);
break;
case GT_BIN16U_BIN16U:
*(Lng32 *)op_data[0] = (*(unsigned short *)op_data[1] > *(unsigned short *)op_data[2]);
break;
case GT_BIN16U_BIN32U:
*(Lng32 *)op_data[0] = (*(unsigned short *)op_data[1] > *(ULng32 *)op_data[2]);
break;
case GT_BIN32S_BIN16S:
*(Lng32 *)op_data[0] = (*(Lng32 *)op_data[1] > *(short *)op_data[2]);
break;
case GT_BIN32S_BIN32S:
*(Lng32 *)op_data[0] = (*(Lng32 *)op_data[1] > *(Lng32 *)op_data[2]);
break;
case GT_BIN32S_BIN16U:
*(Lng32 *)op_data[0] = (*(Lng32 *)op_data[1] > *(unsigned short *)op_data[2]);
break;
case GT_BIN32S_BIN32U:
*(Lng32 *)op_data[0] = ((Int64)*(Lng32 *)op_data[1] > (Int64)*(ULng32 *)op_data[2]);
break;
case GT_BIN32U_BIN16S:
*(Lng32 *)op_data[0] = ((Int64)*(ULng32 *)op_data[1] > *(short *)op_data[2]);
break;
case GT_BIN32U_BIN32S:
*(Lng32 *)op_data[0] = ((Int64)*(ULng32 *)op_data[1] > (Int64)*(Lng32 *)op_data[2]);
break;
case GT_BIN32U_BIN16U:
*(Lng32 *)op_data[0] = (*(ULng32 *)op_data[1] > *(unsigned short *)op_data[2]);
break;
case GT_BIN32U_BIN32U:
*(Lng32 *)op_data[0] = (*(ULng32 *)op_data[1] > *(ULng32 *)op_data[2]);
break;
case GT_BIN64S_BIN64S:
*(Lng32 *)op_data[0] = (*(Int64 *)op_data[1] > *(Int64 *)op_data[2]);
break;
case GT_BIN64U_BIN64U:
*(Lng32 *)op_data[0] = (*(UInt64 *)op_data[1] > *(UInt64 *)op_data[2]);
break;
case GT_BIN64U_BIN64S:
*(Lng32 *)op_data[0] =
((*(Int64*)op_data[2] < 0) ? 1 :
(*(UInt64 *)op_data[1] > *(Int64 *)op_data[2]));
break;
case GT_BIN64S_BIN64U:
*(Lng32 *)op_data[0] =
((*(Int64*)op_data[1] < 0) ? 0 :
(*(Int64 *)op_data[1] > *(UInt64 *)op_data[2]));
break;
case GT_DECS_DECS:
{
if ((op_data[1][0] & 0200) == 0)
{
// first operand is positive
if ((op_data[2][0] & 0200) == 0)
{
// second operand is positive
if (str_cmp(op_data[1], op_data[2],
(Int32)getOperand(1)->getLength()) > 0) // l > r
*(Lng32 *)op_data[0] = 1;
else
*(Lng32 *)op_data[0] = 0;
}
else
{
// second operand is negative
*(Lng32 *)op_data[0] = 1; // +ve always > -ve
}
}
else
{
// first operand is negative
if ((op_data[2][0] & 0200) == 0)
{
// second operand is positive
*(Lng32 *)op_data[0] = 0; // -ve always <= +ve
}
else
{
// second operand is negative
if (str_cmp(op_data[1], op_data[2],
(Int32)getOperand(1)->getLength()) >= 0) // l >= r
*(Lng32 *)op_data[0] = 0;
else
*(Lng32 *)op_data[0] = 1;
}
} // first operand is negative
}
break;
case GT_DECU_DECU:
case GT_ASCII_F_F:
if (str_cmp(op_data[1], op_data[2], (Int32)getOperand(1)->getLength()) > 0)
*(Lng32 *)op_data[0] = 1;
else
*(Lng32 *)op_data[0] = 0;
break;
case GT_UNICODE_F_F:
// 11/3/97: added for Unicode
if (wc_str_cmp((NAWchar*)op_data[1], (NAWchar*)op_data[2],
(Int32)(getOperand(1)->getLength()) >>1) > 0)
*(Lng32 *)op_data[0] = 1;
else
*(Lng32 *)op_data[0] = 0;
break;
case GT_FLOAT32_FLOAT32:
*(Lng32 *)op_data[0] = (*(float *)op_data[1] > *(float *)op_data[2]);
break;
case GT_FLOAT64_FLOAT64:
*(Lng32 *)op_data[0] = (*(double *)op_data[1] > *(double *)op_data[2]);
break;
case GT_DATETIME_DATETIME:
if (((ExpDatetime *) getOperand(1))->compDatetimes(op_data[1],
op_data[2]) > 0)
*(Lng32 *)op_data[0] = 1;
else
*(Lng32 *)op_data[0] = 0;
break;
// GREATER THAN OR EQUAL TO
case GE_BIN8S_BIN8S:
*(Lng32 *)op_data[0] = (*(Int8 *)op_data[1] >= *(Int8 *)op_data[2]);
break;
case GE_BIN8U_BIN8U:
*(Lng32 *)op_data[0] = (*(UInt8 *)op_data[1] >= *(UInt8 *)op_data[2]);
break;
case GE_BIN16S_BIN16S:
*(Lng32 *)op_data[0] = (*(short *)op_data[1] >= *(short *)op_data[2]);
break;
case GE_BIN16S_BIN32S:
*(Lng32 *)op_data[0] = (*(short *)op_data[1] >= *(Lng32 *)op_data[2]);
break;
case GE_BIN16S_BIN16U:
*(Lng32 *)op_data[0] = (*(short *)op_data[1] >= *(unsigned short *)op_data[2]);
break;
case GE_BIN16S_BIN32U:
*(Lng32 *)op_data[0] = (*(short *)op_data[1] >= (Int64)*(ULng32 *)op_data[2]);
break;
case GE_BIN16U_BIN16S:
*(Lng32 *)op_data[0] = (*(unsigned short *)op_data[1] >= *(short *)op_data[2]);
break;
case GE_BIN16U_BIN32S:
*(Lng32 *)op_data[0] = (*(unsigned short *)op_data[1] >= *(Lng32 *)op_data[2]);
break;
case GE_BIN16U_BIN16U:
*(Lng32 *)op_data[0] = (*(unsigned short *)op_data[1] >= *(unsigned short *)op_data[2]);
break;
case GE_BIN16U_BIN32U:
*(Lng32 *)op_data[0] = (*(unsigned short *)op_data[1] >= *(ULng32 *)op_data[2]);
break;
case GE_BIN32S_BIN16S:
*(Lng32 *)op_data[0] = (*(Lng32 *)op_data[1] >= *(short *)op_data[2]);
break;
case GE_BIN32S_BIN32S:
*(Lng32 *)op_data[0] = (*(Lng32 *)op_data[1] >= *(Lng32 *)op_data[2]);
break;
case GE_BIN32S_BIN16U:
*(Lng32 *)op_data[0] = (*(Lng32 *)op_data[1] >= *(unsigned short *)op_data[2]);
break;
case GE_BIN32S_BIN32U:
*(Lng32 *)op_data[0] = ((Int64)*(Lng32 *)op_data[1] >= (Int64)*(ULng32 *)op_data[2]);
break;
case GE_BIN32U_BIN16S:
*(Lng32 *)op_data[0] = ((Int64)*(ULng32 *)op_data[1] >= *(short *)op_data[2]);
break;
case GE_BIN32U_BIN32S:
*(Lng32 *)op_data[0] = ((Int64)*(ULng32 *)op_data[1] >= (Int64)*(Lng32 *)op_data[2]);
break;
case GE_BIN32U_BIN16U:
*(Lng32 *)op_data[0] = (*(ULng32 *)op_data[1] >= *(unsigned short *)op_data[2]);
break;
case GE_BIN32U_BIN32U:
*(Lng32 *)op_data[0] = (*(ULng32 *)op_data[1] >= *(ULng32 *)op_data[2]);
break;
case GE_BIN64S_BIN64S:
*(Lng32 *)op_data[0] = (*(Int64 *)op_data[1] >= *(Int64 *)op_data[2]);
break;
case GE_BIN64U_BIN64U:
*(Lng32 *)op_data[0] = (*(UInt64 *)op_data[1] >= *(UInt64 *)op_data[2]);
break;
case GE_BIN64U_BIN64S:
*(Lng32 *)op_data[0] =
((*(Int64*)op_data[2] < 0) ? 1 :
(*(UInt64 *)op_data[1] >= *(Int64 *)op_data[2]));
break;
case GE_BIN64S_BIN64U:
*(Lng32 *)op_data[0] =
((*(Int64*)op_data[1] < 0) ? 0 :
(*(Int64 *)op_data[1] >= *(UInt64 *)op_data[2]));
break;
case GE_DECS_DECS:
{
if ((op_data[1][0] & 0200) == 0)
{
// first operand is positive
if ((op_data[2][0] & 0200) == 0)
{
// second operand is positive
if (str_cmp(op_data[1], op_data[2],
(Int32)getOperand(1)->getLength()) >= 0) // l >= r
*(Lng32 *)op_data[0] = 1;
else
*(Lng32 *)op_data[0] = 0;
}
else
{
// second operand is negative
*(Lng32 *)op_data[0] = 1; // +ve always >= -ve
}
}
else
{
// first operand is negative
if ((op_data[2][0] & 0200) == 0)
{
// second operand is positive
*(Lng32 *)op_data[0] = 0; // -ve always < +ve
}
else
{
// second operand is negative
if (str_cmp(op_data[1], op_data[2],
(Int32)getOperand(1)->getLength()) > 0) // l > r
*(Lng32 *)op_data[0] = 0;
else
*(Lng32 *)op_data[0] = 1;
}
} // first operand is negative
}
break;
case GE_DECU_DECU:
case GE_ASCII_F_F:
if (str_cmp(op_data[1], op_data[2], (Int32)getOperand(1)->getLength()) >= 0)
*(Lng32 *)op_data[0] = 1;
else
*(Lng32 *)op_data[0] = 0;
break;
case GE_UNICODE_F_F:
// 11/3/97: added for Unicode
if (wc_str_cmp((NAWchar*)op_data[1], (NAWchar*)op_data[2],
(Int32)(getOperand(1)->getLength()) >> 1) >= 0)
*(Lng32 *)op_data[0] = 1;
else
*(Lng32 *)op_data[0] = 0;
break;
case GE_FLOAT32_FLOAT32:
*(Lng32 *)op_data[0] = (*(float *)op_data[1] >= *(float *)op_data[2]);
break;
case GE_FLOAT64_FLOAT64:
*(Lng32 *)op_data[0] = (*(double *)op_data[1] >= *(double *)op_data[2]);
break;
case GE_DATETIME_DATETIME:
if (((ExpDatetime *) getOperand(1))->compDatetimes(op_data[1],
op_data[2]) >= 0)
*(Lng32 *)op_data[0] = 1;
else
*(Lng32 *)op_data[0] = 0;
break;
case ASCII_COMP:
case EQ_ASCII_COMP:
case GT_ASCII_COMP:
case GE_ASCII_COMP:
case LT_ASCII_COMP:
case LE_ASCII_COMP:
case NE_ASCII_COMP:
{
Lng32 length1 = getOperand(1)->getLength(op_data[-MAX_OPERANDS + 1]);
Lng32 length2 = getOperand(2)->getLength(op_data[-MAX_OPERANDS + 2]) ;
char padChar = ' ';
if (getCollationEncodeComp())
{
padChar = 0;
}
Int32 compare_code =
charStringCompareWithPad( op_data[1], length1, op_data[2], length2, padChar);
retcode = processResult(compare_code, (Lng32 *)op_data[0],
heap, diagsArea);
break;
}
case UNICODE_COMP: // 11/3/95: Unicode
{
Lng32 length1 = getOperand(1)->getLength(op_data[-MAX_OPERANDS + 1]);
Lng32 length2 = getOperand(2)->getLength(op_data[-MAX_OPERANDS + 2]);
Int32 compare_code =
wcharStringCompareWithPad((NAWchar*)op_data[1], length1>>1,
(NAWchar*)op_data[2], length2>>1,
unicode_char_set::space_char()
);
retcode = processResult(compare_code, (Lng32 *)op_data[0],
heap, diagsArea);
break;
}
// boolean comparison
case EQ_BOOL_BOOL:
{
*(Lng32*)op_data[0] = (*(Int8 *)op_data[1] == *(Int8 *)op_data[2]);
}
break;
case NE_BOOL_BOOL:
{
*(Lng32*)op_data[0] = (*(Int8 *)op_data[1] != *(Int8 *)op_data[2]);
}
break;
case COMP_COMPLEX:
*(Lng32 *)op_data[0] =
((ComplexType *)getOperand(1))->comp(getOperType(), getOperand(2), op_data);
break;
case COMP_NOT_SUPPORTED:
{
// this comparison operation not supported.
// See if it could still be evaluated by doing some intermediate
// operations.
if (evalUnsupportedOperations(op_data, heap, diagsArea) !=
ex_expr::EXPR_OK)
return ex_expr::EXPR_ERROR;
}
break;
default:
ExRaiseSqlError(heap, diagsArea, EXE_INTERNAL_ERROR);
retcode = ex_expr::EXPR_ERROR;
break;
}
if ((getRollupColumnNum() >= 0) &&
(*(Lng32*)op_data[0] == 0) &&
(getExeGlobals()))
{
getExeGlobals()->setRollupColumnNum(getRollupColumnNum());
}
return retcode;
}
ex_expr::exp_return_type ex_comp_clause::evalUnsupportedOperations(
char *op_data[],
CollHeap *heap,
ComDiagsArea** diagsArea)
{
// if this operation could be done by converting to an
// intermediate datatype, do it.
short op1Type = getOperand(1)->getDatatype();
short op2Type = getOperand(2)->getDatatype();
ExRaiseSqlError(heap, diagsArea, EXE_INTERNAL_ERROR);
return ex_expr::EXPR_ERROR;
}