// // The function checks whether or not the function has a correct set of arguments. bool FdoRdbmsMySqlFilterProcessor::HasNativeSupportedFunctionArguments(FdoFunction& expr) const { // If the function needs argument checking, execute the verification and return // the result back to the calling routine. Otherwise, the arguments are always // deemed valid and the corresponding indication is returned. if (FdoCommonOSUtil::wcsicmp(L"STDDEV", expr.GetName()) == 0) { // The signatures for the function STDDEV allow an optional first // parameter that identifies the operation type (ALL, DISTINCT). In // MySQL this is not natively supported. Therefore, instead of sending // the request to MySQL it needs to be redirected to the Expression // Engine. // The following checks for the number of arguments. If there are two // arguments, the request needs to be redirected to the Expression // Engine. return (expr.GetArguments()->GetCount() > 1) ? false : true; } if (FdoCommonOSUtil::wcsicmp(L"TRUNC", expr.GetName()) == 0) { // The signatures for the function TRUNC allow the truncation of date // and numeric data. If the input is data then the request cannot be // handled by MySQL as this is not supported. In this case the request // needs to be handed to the Expression Engine. // NOTE: The current implementation hands the request to the Expression // Engine in all cases. This needs to be updated later. return false; } return true;; }
ThemeParameters* ThemeParameters::Parse(const wchar_t* expressionString) { // parse the expression and see if it consists of one of our theming functions FdoPtr<FdoExpression> expression; try { expression = FdoExpression::Parse(expressionString); } catch (FdoException* e) { ProcessStylizerException(e, __LINE__, __WFILE__); } FdoFunction* function = dynamic_cast<FdoFunction*>(expression.p); if (function != NULL) { FdoString* name = function->GetName(); FdoPtr<FdoExpressionCollection> exprColl = function->GetArguments(); if (_wcsicmp(name, L"lookup") == 0) return new LookupThemeParameters(exprColl); if (_wcsicmp(name, L"range") == 0) return new RangeThemeParameters(exprColl); } // not one of our functions return NULL; }
void FdoRdbmsMySqlFilterProcessor::ProcessFunction (FdoFunction &expr) { FdoStringP funcName = expr.GetName(); // Some of the FDO expression function require special processing. Those // functions are handled next. if ((FdoCommonOSUtil::wcsicmp(funcName, FDO_FUNCTION_AVG ) == 0) || (FdoCommonOSUtil::wcsicmp(funcName, FDO_FUNCTION_COUNT ) == 0) || (FdoCommonOSUtil::wcsicmp(funcName, FDO_FUNCTION_MAX ) == 0) || (FdoCommonOSUtil::wcsicmp(funcName, FDO_FUNCTION_MIN ) == 0) || (FdoCommonOSUtil::wcsicmp(funcName, FDO_FUNCTION_STDDEV) == 0) || (FdoCommonOSUtil::wcsicmp(funcName, FDO_FUNCTION_SUM ) == 0) ) return ProcessAggregateFunction(expr); if ((FdoCommonOSUtil::wcsicmp(funcName, FDO_FUNCTION_TODOUBLE ) == 0) || (FdoCommonOSUtil::wcsicmp(funcName, FDO_FUNCTION_TOFLOAT ) == 0) ) return ProcessToDoubleFloatFunction(expr); if ((FdoCommonOSUtil::wcsicmp(funcName, FDO_FUNCTION_TOINT32 ) == 0) || (FdoCommonOSUtil::wcsicmp(funcName, FDO_FUNCTION_TOINT64 ) == 0) ) return ProcessToInt32Int64Function(expr); if (FdoCommonOSUtil::wcsicmp(funcName, FDO_FUNCTION_CURRENTDATE) == 0) return ProcessCurrentDateFunction(expr); if (FdoCommonOSUtil::wcsicmp(funcName, FDO_FUNCTION_TRIM) == 0) return ProcessTrimFunction(expr); // The functions that do not require special handling use the // standard processing FdoRdbmsFilterProcessor::ProcessFunction(expr); }
// // The TRIM function requires special processing. void FdoRdbmsMySqlFilterProcessor::ProcessTrimFunction( FdoFunction& expr) { // Append the function name and the opening bracket. ProcessFunctionName(expr); AppendString( "( " ); // Process the arguments. This is were the special processing is required. // If the call includes an operator (BOTH, LEADING, TRAILING), it is required // to add a FROM clause after the operation keyword. FdoPtr<FdoExpressionCollection> exprCol = expr.GetArguments(); for ( int i=0; i<exprCol->GetCount(); i++ ) { FdoPtr<FdoExpression>exp = exprCol->GetItem( i ); if ( (i == 0) && (IsDataValue( exp )) ) { FdoDataValue *dataValue = (static_cast<FdoDataValue *>(exp.p) ); if ( dataValue->GetDataType() == FdoDataType_String ) { FdoStringValue *stringValue = static_cast<FdoStringValue *>(dataValue); AppendString( stringValue->GetString() ); AppendString( " FROM " ); } else throw FdoFilterException::Create(NlsMsgGet(FDORDBMS_29, "Unsupported FDO type in expression")); } else HandleExpr( exp ); } AppendString( " )" ); }
void UnitTestProcessor::ProcessFunction(FdoFunction& expr) { prependTabs(); wprintf(L"Function : %s\n", expr.GetName()); FdoExpressionCollection* pColl = expr.GetArguments(); m_tabLevel++; for (FdoInt32 i = 0; i < pColl->GetCount(); i++) { FdoExpression* pExpr; pExpr = pColl->GetItem(i); pExpr->Process(this); pExpr->Release(); } m_tabLevel--; pColl->Release(); }
void FdoRdbmsMySqlFilterProcessor::ProcessToInt32Int64Function (FdoFunction& expr) { // MySQL uses a different native function name for the expression functions // TOINT32, TOINT64. AppendString(MYSQL_FUNCTION_TONUM); AppendString(OPEN_PARENTH); FdoPtr<FdoExpressionCollection> exprCol = expr.GetArguments(); for(int i=0; i<exprCol->GetCount(); i++ ) { if( i!= 0 ) AppendString( L", " ); FdoPtr<FdoExpression>exp = exprCol->GetItem( i ); HandleExpr( exp ); } // Add the keyword that performs the conversion and the closing bracket. AppendString( L", SIGNED)" ); }
void FdoRdbmsMySqlFilterProcessor::ProcessCurrentDateFunction (FdoFunction& expr) { // MySQL uses a different native function name for the expression function // CurrentDate. AppendString(MYSQL_FUNCTION_CURRENTDATE); AppendString(OPEN_PARENTH); // Note, that the function does not allow any arguments. However, if some // are given, they are added to the function call and it is left to MySQL // to deal with it. FdoPtr<FdoExpressionCollection> exprCol = expr.GetArguments(); for(int i=0; i<exprCol->GetCount(); i++ ) { if( i!= 0 ) AppendString( L", " ); FdoPtr<FdoExpression>exp = exprCol->GetItem( i ); HandleExpr( exp ); } AppendString( CLOSE_PARENTH ); }
// // Aggregate functions require special processing because of the optional // first parameter. The value of this parameter may be ALL or DISTINCT. void FdoRdbmsMySqlFilterProcessor::ProcessAggregateFunction (FdoFunction& expr) { // Append the function name and the opening bracket. ProcessFunctionName(expr); AppendString( "( " ); // Process the arguments. This is were the special processing is required as // it is required to have the parameters listed sequencially without a comma // between them. FdoPtr<FdoExpressionCollection> exprCol = expr.GetArguments(); for (int i=0; i<exprCol->GetCount(); i++) { FdoPtr<FdoExpression>exp = exprCol->GetItem(i); if ((i == 0) && (IsDataValue(exp))) { FdoDataValue *dataValue = (static_cast<FdoDataValue *>(exp.p)); if (dataValue->GetDataType() == FdoDataType_String) { // Omit ALL if specified as this keyword is not supported in // MySQL. FdoStringValue *stringValue = static_cast<FdoStringValue *>(dataValue); FdoStringP strValue = stringValue->GetString(); if (FdoCommonOSUtil::wcsicmp(strValue, L"ALL") != 0) { AppendString(stringValue->GetString()); AppendString(L" "); } } else throw FdoFilterException::Create(NlsMsgGet(FDORDBMS_29, "Unsupported FDO type in expression")); } else HandleExpr(exp); } AppendString(" )"); }
FdoRdbmsFeatureReader *FdoRdbmsSelectCommand::GetOptimizedFeatureReader( const FdoSmLpClassDefinition *classDefinition ) { // Verify if this is a special case we can optimize (no grouping filter, // and only aggregate functions Count() and/or SpatialExtents()) FdoRdbmsFeatureReader *reader = NULL; bool bOtherAggrSelected = false; aggr_list *selAggrList = new aggr_list; if ( (classDefinition->GetClassType() == FdoClassType_FeatureClass ) && mIdentifiers && !mGroupingCol) { for (int i = 0; i < mIdentifiers->GetCount() && !bOtherAggrSelected; i++ ) { FdoPtr<FdoIdentifier> identifier = mIdentifiers->GetItem(i); FdoComputedIdentifier* computedIdentifier = dynamic_cast<FdoComputedIdentifier*>(identifier.p); if (computedIdentifier) { FdoPtr<FdoExpression> expr = computedIdentifier->GetExpression(); FdoFunction* func = dynamic_cast<FdoFunction*>(expr.p); if (func && 0==FdoCommonOSUtil::wcsicmp(func->GetName(), FDO_FUNCTION_SPATIALEXTENTS)) { FdoPtr<FdoExpressionCollection> args = func->GetArguments(); FdoPtr<FdoExpression> arg = args->GetItem(0); FdoIdentifier* argId = dynamic_cast<FdoIdentifier*>(arg.p); AggregateElement *id = new AggregateElement; id->propName = argId->GetName(); id->name = computedIdentifier->GetName(); id->type = FdoPropertyType_GeometricProperty; selAggrList->push_back( id ); } else if (func && 0 == FdoCommonOSUtil::wcsicmp(func->GetName(), FDO_FUNCTION_COUNT)) { // Only if the argument count for the function is 1 do some // special handling. FdoPtr<FdoExpressionCollection> exprArgColl = func->GetArguments(); if (exprArgColl->GetCount() == 1) { AggregateElement *id = new AggregateElement; id->name = computedIdentifier->GetName(); id->type = FdoPropertyType_DataProperty; selAggrList->push_back( id ); } else { bOtherAggrSelected = true; } } else { bOtherAggrSelected = true; } } } } // Now perform the actual select aggregates and return the data reader: if ( !bOtherAggrSelected && ( selAggrList->size() > 0 )) { reader = mFdoConnection->GetOptimizedAggregateReader( classDefinition, selAggrList, GetFilterRef() ); // The reader takes ownership of the selAggrList } else { // Sorry, no optimization. Clean up. for ( size_t j = 0; j < selAggrList->size(); j++ ) delete selAggrList->at(j); delete selAggrList; } return reader; }