📄 compare.c
字号:
int *offset; mVal_t *tmpVal;{ int tmp = 0; char int8; short int16; int int32; double fv; char *cp;#ifdef HUGE_T HUGE_T int64;#endif if (curCond->sysvar) { tmp = sysvarCompare(cacheEntry,row, curCond, value); return(tmp); } /* ** Check to see if there is a type specific comparison routine */ switch(curCond->type) { case CIDR4_TYPE: if (ISA_LIKE_OP(curCond->op)) { strcpy(errMsg, LIKE_ERROR); debugTrace(TRACE_OUT,"processCondMatch()"); return(-2); } tmp = cidr4Match((data + *offset + 1), value->val.byteVal, curCond->op); if (tmp < 0) return(-2); return(tmp); break; } /* ** If not just use the base type's comparison routine */ switch(typeBaseType(curCond->type)) { case INT_TYPE: if (ISA_LIKE_OP(curCond->op)) { strcpy(errMsg, INT_LIKE_ERROR); debugTrace(TRACE_OUT,"processCondMatch()"); return(-2); } bcopy4((data + *offset +1), &int32); intMatch(int32,value->val.intVal,curCond->op,tmp); break; case INT8_TYPE: if (ISA_LIKE_OP(curCond->op)) { strcpy(errMsg, INT_LIKE_ERROR); debugTrace(TRACE_OUT,"processCondMatch()"); return(-2); } bcopy((data + *offset +1), &int8, 1); intMatch(int8,value->val.intVal,curCond->op,tmp); break; case INT16_TYPE: if (ISA_LIKE_OP(curCond->op)) { strcpy(errMsg, INT_LIKE_ERROR); debugTrace(TRACE_OUT,"processCondMatch()"); return(-2); } bcopy((data + *offset +1), &int16, 2); intMatch(int16,value->val.intVal,curCond->op,tmp); break; case UINT_TYPE: if (ISA_LIKE_OP(curCond->op)) { strcpy(errMsg, INT_LIKE_ERROR); debugTrace(TRACE_OUT,"processCondMatch()"); return(-2); } bcopy4((data + *offset +1), &int32); uintMatch(int32,value->val.intVal,curCond->op,tmp); break; case UINT8_TYPE: if (ISA_LIKE_OP(curCond->op)) { strcpy(errMsg, INT_LIKE_ERROR); debugTrace(TRACE_OUT,"processCondMatch()"); return(-2); } bcopy((data + *offset +1), &int8, 1); uintMatch(int8,value->val.intVal,curCond->op,tmp); break; case UINT16_TYPE: if (ISA_LIKE_OP(curCond->op)) { strcpy(errMsg, INT_LIKE_ERROR); debugTrace(TRACE_OUT,"processCondMatch()"); return(-2); } bcopy((data + *offset +1), &int16, 2); uintMatch(int16,value->val.intVal,curCond->op,tmp); break;#ifdef HUGE_T case INT64_TYPE: if (ISA_LIKE_OP(curCond->op)) { strcpy(errMsg, INT_LIKE_ERROR); debugTrace(TRACE_OUT,"processCondMatch()"); return(-2); } bcopy((data + *offset +1), &int64, sizeof(HUGE_T)); int64Match(int64,value->val.int64Val,curCond->op,tmp); break; case UINT64_TYPE: if (ISA_LIKE_OP(curCond->op)) { strcpy(errMsg, INT_LIKE_ERROR); debugTrace(TRACE_OUT,"processCondMatch()"); return(-2); } bcopy((data + *offset +1), &int64, sizeof(HUGE_T)); uint64Match(int64,value->val.int64Val,curCond->op,tmp); break;#endif case CHAR_TYPE: if (curCond->sysvar) { tmp = sysvarCompare(cacheEntry,row, curCond, value); return(tmp); } cp = (char *)data + *offset +1; tmp = charMatch(cp,value->val.charVal, curCond->op, curCond->length); if (value == tmpVal) { free(tmpVal->val.charVal); tmpVal->val.charVal = NULL; } if (tmp < 0) { debugTrace(TRACE_OUT,"processCondMatch()"); return(-2); } break; case TEXT_TYPE: cp = (char *)data + *offset +1; if (curCond->op == RLIKE_OP || curCond->op == SLIKE_OP) { strcpy(errMsg, TEXT_REGEX_ERROR); debugTrace(TRACE_OUT,"processCondMatch()"); return(-2); } tmp = varcharMatch(cacheEntry,cp, value->val.charVal, curCond->length, curCond->op); if (value == tmpVal) { free(tmpVal->val.charVal); tmpVal->val.charVal = NULL; } if (tmp < 0) { debugTrace(TRACE_OUT,"processCondMatch()"); return(-2); } break; case REAL_TYPE: if (curCond->sysvar) { tmp = sysvarCompare(cacheEntry,row, curCond, value); return(tmp); } bcopy8((data + *offset + 2),&fv); if (ISA_LIKE_OP(curCond->op)) { strcpy(errMsg, REAL_LIKE_ERROR); debugTrace(TRACE_OUT,"processCondMatch()"); return(-2); } realMatch(fv,value->val.realVal, curCond->op, tmp); break; case BYTE_TYPE: if (ISA_LIKE_OP(curCond->op)) { strcpy(errMsg, LIKE_ERROR); debugTrace(TRACE_OUT,"processCondMatch()"); return(-2); } tmp = byteRangeMatch((data + *offset +1), value->val.byteVal, curCond->op, curCond->length); break; } return(tmp);} /**************************************************************************** PUBLIC ROUTINES**************************************************************************/int compareMatchRow(cacheEntry,row,conds,query) cache_t *cacheEntry; row_t *row; mCond_t *conds; mQuery_t *query;{ mCond_t *curCond; int result, freeTmpField = 0, tmp = 0; int *offset, init=1, res; u_char *data; mVal_t *value, tmpVal; mField_t *curField, tmpField, *tmpFieldPtr; int tmpFlist[2], foundField; int rhsType; /* saves rhs type prior to data fetch */ int lhsIsNull;/* temporary that indicates nullness of lhs */ debugTrace(TRACE_IN,"compareMatchRow()"); result=0; if (!conds) { debugTrace(TRACE_OUT,"compareMatchRow()"); return(1); } data = row->data; curCond = conds; offset = conds->clist; while(curCond) { /* ** If this is a subcond just recurse and continue */ if (curCond->subCond) { tmp = compareMatchRow(cacheEntry,row,curCond->subCond, query); if (tmp < 0) return(tmp); if (init) { result = tmp; init = 0; } else { switch(curCond->bool) { case NO_BOOL: result = tmp; break; case AND_BOOL: result &= tmp; break; case OR_BOOL: result |= tmp; break; } } curCond = curCond->next; continue; } /* ** OK, it wasn't a sub cond. Proceded as normal. ** ** If we are comparing 2 fields (e.g. in a join) then ** grab the value of the second field so that we can do ** the comparison. Watch for type mismatches! */ foundField = 0; freeTmpField = 0; tmpField.value = NULL; rhsType = curCond->value->type; switch(curCond->value->type) { case IDENT_TYPE: value = curCond->value; curField = cacheEntry->def; if (!*(value->val.identVal->seg1)) { if (!cacheEntry->result) { strcpy(value->val.identVal->seg1, cacheEntry->table); } else { strcpy(errMsg,UNQUAL_ERROR); debugTrace(TRACE_OUT, "compareMatchRow()"); return(-1); } } while(curField) { if (*(curField->table) != *(value->val.identVal->seg1) || *(curField->name) != *(value->val.identVal->seg2)) { curField = curField->next; continue; } if (strcmp(curField->table, value->val.identVal->seg1) != 0 || strcmp(curField->name, value->val.identVal->seg2) != 0) { curField = curField->next; continue; } tmpFieldPtr = &tmpField; memCopyField(curField,tmpFieldPtr); tmpField.value=NULL; tmpField.next = NULL; utilSetupFields(cacheEntry,tmpFlist, &tmpField); tableExtractValues(cacheEntry,row,&tmpField, tmpFlist, query); bcopy(tmpField.value,&tmpVal,sizeof(mVal_t)); /* RNS * Character data needs to be copied, but * only if there is data. */ if (tmpVal.type == CHAR_TYPE && !tmpVal.nullVal) { tmpVal.val.charVal= (u_char*) malloc(curField->length + 1); bcopy(tmpField.value->val.charVal, tmpVal.val.charVal, curField->length); *(tmpVal.val.charVal+curField->length) = 0; } parseFreeValue(tmpField.value); tmpField.value = NULL; value = &tmpVal; foundField = 1; break; } if (!foundField) { snprintf(errMsg, MAX_ERR_MSG, BAD_FIELD_ERROR, value->val.identVal->seg1, value->val.identVal->seg2); msqlDebug2(MOD_ERR,"Unknown field \"%s.%s\"\n", value->val.identVal->seg1, value->val.identVal->seg2); debugTrace(TRACE_OUT,"compareMatchRow()"); return(-1); } break; case SYSVAR_TYPE: strcpy(tmpField.name, curCond->value->val.identVal->seg2); res = sysvarCheckVariable(cacheEntry, &tmpField); if (res == -2) return(-1); if (res == -1) { snprintf(errMsg, MAX_ERR_MSG, SYSVAR_ERROR, curCond->value->val.identVal->seg2); return(-1); } sysvarGetVariable(cacheEntry,row,&tmpField,query); value = tmpField.value; freeTmpField = 1; break; default: value = curCond->value; break; } /* ** Ensure that the comparison is with the correct type. ** We do this here and in utilSetupConds() as we have to wait ** for the evaluation of field to field comparisons. We ** also fudge it for real/int comparisons. It's done ** in msqlutilpConds() to handle cases going to the ** index lookup code and for literal comparisons. */ if(utilSetCondValueType(curCond, value) < 0) { if (freeTmpField) parseFreeValue(tmpField.value); return(-1); } /* ** O.K. do the actual comparison */ if (*offset >=0) { lhsIsNull = (*(data + *offset) == 0); } else { /* ** Offset of -1 indicates a sysvar we don't ** check the table data for a NULL value */ lhsIsNull = 0; } if ((rhsType == NULL_TYPE) && ISA_NULL_OP(curCond->op)) { /* ** An explicit comparison to NULL. */ byteMatch( *(data + *offset), 0, curCond->op, tmp ); } else if (rhsType == NULL_TYPE) { /* ** SQL does not allow other operators for NULL. */ strcpy(errMsg, "Illegal operator applied to NULL.\n" ); debugTrace(TRACE_OUT,"compareMatchRow()"); return(-1); } else if (value->nullVal || lhsIsNull) { /* * SQL says that any compare of implicit NULL values * should always fail (return false for now). */ tmp = 0; } else { if (curCond->op == BETWEEN_OP) { tmp = processBetweenMatch(cacheEntry, curCond, data, offset, tmpVal); } else { tmp = processCondMatch(cacheEntry,curCond, value,row, data, offset, &tmpVal); } } if (freeTmpField) parseFreeValue(tmpField.value); if (tmp == -2) return(-1); if (init) { result = tmp; init = 0; } else { switch(curCond->bool) { case NO_BOOL: result = tmp; break; case AND_BOOL: result &= tmp; break; case OR_BOOL: result |= tmp; break; } } curCond = curCond->next; offset++; } debugTrace(TRACE_OUT,"compareMatchRow()"); return(result);}int compareRows(entry,r1,r2,order,olist) cache_t *entry; row_t *r1, *r2; mOrder_t *order; int *olist;{ mOrder_t *curOrder; char buf[sizeof(double)], *cp1, *cp2; u_char *data1, *data2; int res = 0, *offset, d1IsNull, d2IsNull; double fp1, fp2; int int4p1, int4p2;#ifdef HUGE_T HUGE_T int64p1, int64p2;#endif /* ** Allow for cases when rows are not defined */ debugTrace(TRACE_IN,"compareRows()"); if (r1 && !r2) { debugTrace(TRACE_OUT,"compareRows()"); return(-1); } if (!r1 && r2) { debugTrace(TRACE_OUT,"compareRows()"); return(1); } if (!r1 && !r2) { debugTrace(TRACE_OUT,"compareRows()"); return(0); } /* ** OK, we have both rows. */ data1 = r1->data; data2 = r2->data; curOrder = order; offset = olist; while(curOrder) { /* RNS * Allow for cases where data is not defined i.e., * try to do something reasonable with null values. * How should we compare them? * For now, treat them as less than anything else. */ d1IsNull = (*(data1 + *offset) == 0); d2IsNull = (*(data2 + *offset) == 0); if (d1IsNull || d2IsNull) { if (d1IsNull && d2IsNull) { res = 0; } else if (d1IsNull) { res = -1; } else { res = 1; } } else switch(typeBaseType(curOrder->type)) { case INT_TYPE: case UINT_TYPE: bcopy4((data1 + *offset +1),buf); int4p1 = (int) * (int*)buf; bcopy4((data2 + *offset +1),buf); int4p2 = (int) * (int*)buf; if (int4p1 == int4p2) res = 0; if (int4p1 > int4p2) res = 1; if (int4p1 < int4p2) res = -1; break;#ifdef HUGE_T case INT64_TYPE: case UINT64_TYPE: bcopy((data1 + *offset +1),buf, sizeof(HUGE_T)); int64p1 = (HUGE_T) * (HUGE_T*)buf; bcopy((data2 + *offset +1),buf, sizeof(HUGE_T)); int64p2 = (HUGE_T) * (HUGE_T*)buf; if (int64p1 == int64p2) res = 0; if (int64p1 > int64p2) res = 1; if (int64p1 < int64p2) res = -1; break;#endif case CHAR_TYPE: cp1 = (char *)data1 + *offset +1; cp2 = (char *)data2 + *offset +1;#ifdef HAVE_STRCOLL res = strcoll(cp1,cp2);#else res = strncmp(cp1,cp2,curOrder->length);#endif break; case REAL_TYPE: bcopy8((data1+*offset+2),buf); fp1 = (double) * (double *)(buf); bcopy8((data2+*offset+2),buf); fp2 = (double) * (double *)(buf); if (fp1 == fp2) res = 0; if (fp1 > fp2) res = 1; if (fp1 < fp2) res = -1; break; case TEXT_TYPE: cp1 = (char *)data1 + *offset +1; cp2 = (char *)data2 + *offset +1; res = varcharCompare(curOrder->entry, cp1, cp2, curOrder->length); break; case BYTE_TYPE: cp1 = (char *)data1 + *offset +1; cp2 = (char *)data2 + *offset +1; res = localByteCmp(cp1,cp2,curOrder->length); break; } if (curOrder->dir == DESC) { res = 0 - res; } if (res != 0) { debugTrace(TRACE_OUT,"compareRows()"); return(res); } curOrder = curOrder->next; offset++; } debugTrace(TRACE_OUT,"compareRows()"); return(0);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -