metadataengine/server/src/mdsfindsqlclause.cpp
changeset 0 c53acadfccc6
child 14 646a02f170b9
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/metadataengine/server/src/mdsfindsqlclause.cpp	Mon Jan 18 20:34:07 2010 +0200
@@ -0,0 +1,2915 @@
+/*
+* Copyright (c) 2007-2009 Nokia Corporation and/or its subsidiary(-ies). 
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:  Class constructs SQL search clauses for MdS.*
+*/
+
+// INCLUDE FILES
+#include "mdsfindsqlclause.h"
+#include "mdsfindsqlclausedef.h"
+#include "mdsclausebuffer.h"
+#include "mdcserializationbuffer.h"
+#include "mdsquerycriteriadeserialization.h"
+#include "mdsobjectdef.h"
+#include "mderange.h"
+#include "mdsschema.h"
+#include "mdsnamespacedef.h"
+#include "mdspropertydef.h"
+#include "mdcquery.h"
+#include "mdeinternalerror.h"
+
+const TInt KQueryBufInitialSize = 512;
+
+// ---------------------------------------------------------------------------
+// NewL
+// ---------------------------------------------------------------------------
+//
+CMdSFindSqlClause* CMdSFindSqlClause::NewL(CMdsSchema& aSchema)
+    {
+    CMdSFindSqlClause* self = NewLC(aSchema);
+    CleanupStack::Pop( self );
+    return self;
+    }
+
+// ---------------------------------------------------------------------------
+// NewLC
+// ---------------------------------------------------------------------------
+//
+CMdSFindSqlClause* CMdSFindSqlClause::NewLC(CMdsSchema& aSchema)
+    {
+    CMdSFindSqlClause* self = new ( ELeave ) CMdSFindSqlClause(aSchema);
+    CleanupStack::PushL( self );
+    self->ConstructL();
+    return self;
+    }
+
+// ---------------------------------------------------------------------------
+// ~CMdSSqlClause
+// ---------------------------------------------------------------------------
+//
+CMdSFindSqlClause::~CMdSFindSqlClause()
+    {
+    delete iQueryBuf;
+
+    iResultRow.Close();
+    iVariables.Close();
+
+    // doesn't own property definitions
+	iPropertyFilters.Close();
+	
+	iFreeText.ResetAndDestroy();
+	iFreeText.Close();
+	
+	if( iSourceObjectDefs )
+		{
+		iSourceObjectDefs->Close();
+
+		delete iSourceObjectDefs;
+		}
+    }
+
+// ---------------------------------------------------------------------------
+// CMdSSqlClause
+// ---------------------------------------------------------------------------
+//
+CMdSFindSqlClause::CMdSFindSqlClause(CMdsSchema& aSchema) : 
+    iVariables(), iQueryBuf( NULL ), iSchema( aSchema ), 
+    iSearchCriteria( NULL ), iSerializedBuffer( NULL ), 
+    iUserLevel( EUserLevelNone ), iNamespaceDef( NULL ), iObjectDef( NULL ), 
+    iSourceObjectDef ( NULL ), iSourceObjectDefs( NULL ), 
+    iAppendToResultRow( ETrue ), iIncludeFreetexts( ETrue ), 
+    iIncludeNotPresent( EFalse ), iNoObjectLocking( ETrue ), iPlaceholdersOnly( EFalse )
+    {
+    }
+
+// ---------------------------------------------------------------------------
+// ConstructL
+// ---------------------------------------------------------------------------
+//
+void CMdSFindSqlClause::ConstructL()
+    {
+    // Construct empty buffer for sql query
+    iQueryBuf = CMdsClauseBuffer::NewL( KQueryBufInitialSize );
+    iQueryBuf->AppendL( KEmpty );
+    }
+
+// ---------------------------------------------------------------------------
+// AsText           Returns sql clause
+// ---------------------------------------------------------------------------
+//
+const TDesC& CMdSFindSqlClause::AsTextL() const
+    {
+    return iQueryBuf->ConstBufferL();
+    }
+
+// ---------------------------------------------------------------------------
+// Variables        Query variables
+// ---------------------------------------------------------------------------
+//
+RRowData& CMdSFindSqlClause::Variables()
+    {
+    return iVariables;
+    }
+
+// ---------------------------------------------------------------------------
+// Variables        Query result row
+// ---------------------------------------------------------------------------
+//
+RRowData& CMdSFindSqlClause::ResultRow()
+    {
+    return iResultRow;
+    }
+
+// ---------------------------------------------------------------------------
+// Limit        Query row limit
+// ---------------------------------------------------------------------------
+//
+TUint32 CMdSFindSqlClause::Limit()
+	{
+	return iSearchCriteria->iLimit;
+	}
+	
+TBool CMdSFindSqlClause::IncludesFreetexts()
+	{
+	return iIncludeFreetexts;
+	}
+
+TQueryType CMdSFindSqlClause::QueryType()
+	{
+	return (TQueryType)iSearchCriteria->iQueryType;
+	}
+
+TQueryResultMode CMdSFindSqlClause::ResultMode()
+	{
+	return (TQueryResultMode)iSearchCriteria->iQueryResultType;
+	}
+
+RPointerArray<HBufC>& CMdSFindSqlClause::QueryFreeText()
+	{
+	return iFreeText;
+	}
+
+TBool CMdSFindSqlClause::NoObjectLocking()
+	{
+	return iNoObjectLocking;
+	}
+
+// ---------------------------------------------------------------------------
+// ObjectDef        Query object definition
+// ---------------------------------------------------------------------------
+//
+CMdsObjectDef* CMdSFindSqlClause::ObjectDef()
+	{
+	return iObjectDef;
+	}
+
+RPointerArray<CMdsPropertyDef>& CMdSFindSqlClause::PropertyFilters()
+	{
+	return iPropertyFilters;
+	}
+
+// ---------------------------------------------------------------------------
+// NamespaceDef        Query namespace definition
+// ---------------------------------------------------------------------------
+//
+CMdsNamespaceDef* CMdSFindSqlClause::NamespaceDef()
+	{
+	return iNamespaceDef;
+	}
+
+// ---------------------------------------------------------------------------
+// CreateL          Creates whole sql clause
+// ---------------------------------------------------------------------------
+//
+void CMdSFindSqlClause::CreateL( 
+	CMdCSerializationBuffer& aSerializedCriteria, 
+	TUserLevel aUserLevel )
+    {
+    iUserLevel = aUserLevel;
+
+    iSerializedBuffer = &aSerializedCriteria;
+
+    iSearchCriteria = CONST_CAST( TMdCSearchCriteria*, 
+    		&TMdCSearchCriteria::GetFromBufferL( aSerializedCriteria ) );
+
+	// can freetexts drop from results
+	if( ( iSearchCriteria->iOptimizationFlags & EContainsFreetextCondition ) == 0 )
+		{
+		iIncludeFreetexts = EFalse;
+		}
+
+	if( iSearchCriteria->iOptimizationFlags & EContainsNotPresentCondition )
+		{
+		iIncludeNotPresent = ETrue;
+		}
+
+	if( iSearchCriteria->iOptimizationFlags & EContainsObjectLocking )
+		{
+		iNoObjectLocking = EFalse;
+		}
+	
+	if( iSearchCriteria->iOptimizationFlags & EContainsPlaceholdersOnly )
+        {
+        iPlaceholdersOnly = ETrue;
+        }
+	
+
+	// get namespace def from new schema definition
+	iNamespaceDef = const_cast<CMdsNamespaceDef*>(iSchema.GetNamespaceByIdL( 
+			iSearchCriteria->iNamespaceDefId ));
+
+	if ( iNamespaceDef )
+		{
+		iNamespaceIdDes.Num( iNamespaceDef->GetId() );
+		}
+	else
+		{
+		User::Leave( KErrMdEUnknownNamespaceDef );
+		}
+
+	iObjectDef = NULL;
+
+	if( iSearchCriteria->iObjectDefId != KNoDefId )
+		{
+		// get object def from new schema definition
+		iObjectDef = CONST_CAST( CMdsObjectDef*, 
+				iNamespaceDef->GetObjectByIdL( iSearchCriteria->iObjectDefId ) );
+
+		if ( !iObjectDef )
+			{
+			User::Leave( KErrMdEUnknownObjectDef );
+			}
+		}
+
+	iSourceObjectDef = NULL;
+	iSourceObjectDefs = NULL;
+
+	if ( iSearchCriteria->iObjectDefIds.iPtr.iCount > 0 )
+		{
+		iSourceObjectDefs = new (ELeave) RArray<TDefId>( 
+				iSearchCriteria->iObjectDefIds.iPtr.iCount );
+		iSourceObjectDefs->ReserveL( iSearchCriteria->iObjectDefIds.iPtr.iCount );
+
+		iSerializedBuffer->PositionL( iSearchCriteria->iObjectDefIds.iPtr.iOffset );
+
+		for( TUint32 i = 0; i < iSearchCriteria->iObjectDefIds.iPtr.iCount; i++ )
+			{
+			TDefId objectDefId;
+			iSerializedBuffer->ReceiveL( objectDefId );			
+			iSourceObjectDefs->Append( objectDefId );
+			}
+		}
+	else
+		{
+		iSourceObjectDef = iObjectDef;
+		}
+
+	if( !iSourceObjectDefs )
+		{
+		// Construct beginning of the select clause 
+		// Format: SELECT [column list/count(*)] FROM table name
+		AppendSelectStatementL();
+
+		AppendWhereStatementL();
+
+		// if query type is object query and freetext are included
+		// "GROUP BY BO.ObjectId"
+		if( iIncludeFreetexts )
+			{
+		    AppendGroupByL();
+			}
+		}
+	else
+		{
+		const TInt sourceObjectDefsCount = iSourceObjectDefs->Count();
+		for( TInt i = 0; i < sourceObjectDefsCount; i++ )
+			{
+			const TDefId sourceObjectDefId = (*iSourceObjectDefs)[i];
+			iSourceObjectDef = CONST_CAST( CMdsObjectDef*, 
+					iNamespaceDef->GetObjectByIdL( sourceObjectDefId ) );
+
+			if( i > 0 )
+				{
+				iAppendToResultRow = EFalse;
+				iQueryBuf->AppendL( KUnionAll );
+				}
+
+			// Construct beginning of the select clause 
+			// Format: SELECT [column list/count(*)] FROM table name
+			AppendSelectStatementL();
+			
+			AppendWhereStatementL();
+			    
+			// if query type is object query and freetext are included
+			// "GROUP BY BO.ObjectId"
+			if( iIncludeFreetexts )
+				{
+			    AppendGroupByL();
+				}
+			}
+		}
+
+    // ORDER BY clause (if such exists)
+    AppendOrderByL();
+
+    // LIMIT and OFFSET clauses (if such exists)
+    AppendLimitAndOffsetL();
+
+    // SQL clause must end to semicolon
+    iQueryBuf->AppendL( KSemicolon );
+    }
+
+// ---------------------------------------------------------------------------
+// AppendPropertyFiltersL       Appends the property filters
+// ---------------------------------------------------------------------------
+//
+void CMdSFindSqlClause::AppendPropertyFiltersL( TBool aDistinct )
+	{
+	if( iSearchCriteria->iPropertyFilters.iPtr.iCount > 0 )
+		{
+		iSerializedBuffer->PositionL( 
+				iSearchCriteria->iPropertyFilters.iPtr.iOffset );
+
+		for ( TUint32 i = 0; i < iSearchCriteria->iPropertyFilters.iPtr.iCount; ++i )
+			{
+			TDefId id;
+			iSerializedBuffer->ReceiveL( id );
+
+			if ( !aDistinct )
+				{
+				iQueryBuf->AppendL( KComma );
+				}
+
+			AppendColumnByPropertyDefIdL( id, KNoDefId, ETrue );
+			}
+
+		iQueryBuf->AppendL( KSpace );
+		}
+	}
+
+// ---------------------------------------------------------------------------
+// AppendSelectStatementL       Appends the SELECT statements
+// ---------------------------------------------------------------------------
+//
+void CMdSFindSqlClause::AppendSelectStatementL()
+    {
+    switch( iSearchCriteria->iQueryType )
+    	{
+    	case EQueryTypeObject:
+    		AppendSelectForObjectL();
+    		AppendFromForObjectL();
+	    	break;
+	    case EQueryTypeRelation:
+	    	AppendSelectForRelationL();
+	    	AppendFromForRelationL();
+	    	break;
+        case EQueryTypeEvent:
+	    	AppendSelectForEventL();
+  	 		AppendFromForEventL();
+	    	break;
+	    default:
+#ifdef _DEBUG
+            User::Panic( _L("MdSFCASS") , KErrMdEUnknownQueryType );
+#endif
+	    	User::Leave( KErrMdEUnknownQueryType );
+    	}
+    }
+
+// ---------------------------------------------------------------------------
+// AppendSelectCountStatementL        SELECT statements for count query
+// ---------------------------------------------------------------------------
+//
+void CMdSFindSqlClause::AppendSelectCountStatementL()
+    {
+    // if result rows needs to be grouped return just "1"
+    if( iIncludeFreetexts )
+		{
+		// "SELECT 1 "
+		iQueryBuf->AppendL( KSelect1 );
+		}
+	else
+		{
+		// "SELECT count(*) "
+    	iQueryBuf->AppendL( KSelectCount );
+		}
+
+	// expected result count
+    if( iAppendToResultRow )
+    	{
+    	iResultRow.AppendL( TColumn( EColumnUint32 ) );
+    	}
+    }
+
+// ---------------------------------------------------------------------------
+// AppendSelectDistinctStatementL   SELECT statements for distinct value query
+// ---------------------------------------------------------------------------
+//
+void CMdSFindSqlClause::AppendSelectDistinctStatementL()
+	{
+	// "SELECT DISTINCT "
+	iQueryBuf->AppendL( KSelectDistinct );
+
+	const TUint32 position = iSerializedBuffer->Position();
+
+	// "column name" (from property filter)
+	AppendPropertyFiltersL( ETrue );
+
+	iSerializedBuffer->PositionL( position );
+	}
+
+// ---------------------------------------------------------------------------
+// AppendSelectObjectIdStatementL        SELECT statements for object id query
+// ---------------------------------------------------------------------------
+//
+void CMdSFindSqlClause::AppendSelectObjectIdStatementL()
+	{
+	// "SELECT BO.ObjectId "
+	iQueryBuf->AppendL( KSelectObjectIds );
+
+	// expected result object ID
+	if( iAppendToResultRow )
+		{
+		iResultRow.AppendL( TColumn( EColumnTItemId ) );
+		}
+	}
+
+// ---------------------------------------------------------------------------
+// AppendSelectEventAllStatementL        SELECT statements for event query
+// ---------------------------------------------------------------------------
+//
+void CMdSFindSqlClause::AppendSelectAllFromEventStatementL()
+	{
+	// "SELECT * "
+	iQueryBuf->AppendL( KSelectAllFrom );
+
+	if( iAppendToResultRow )
+		{
+		// expected result Events 
+	    iResultRow.AppendL( TColumn( EColumnTItemId ) );
+	    iResultRow.AppendL( TColumn( EColumnTItemId ) );
+	    iResultRow.AppendL( TColumn( EColumnTDefId ) );
+	    iResultRow.AppendL( TColumn( EColumnTime ) );
+	    iResultRow.AppendL( TColumn( EColumnDes16 ) );
+	    iResultRow.AppendL( TColumn( EColumnDes16 ) );
+		}
+	}
+
+// ---------------------------------------------------------------------------
+// AppendSelectRelationAllStatementL        SELECT statements for Relaltion query
+// ---------------------------------------------------------------------------
+//
+void CMdSFindSqlClause::AppendSelectAllFromRelationStatementL()
+	{
+	// "SELECT * "
+	iQueryBuf->AppendL( KSelectAllFrom );
+
+	if( iAppendToResultRow )
+		{
+		// expected result Relation
+	    iResultRow.AppendL( TColumn( EColumnTItemId ) );
+	    iResultRow.AppendL( TColumn( EColumnUint32 ) );
+	    iResultRow.AppendL( TColumn( EColumnTDefId ) );
+	    iResultRow.AppendL( TColumn( EColumnTItemId ) );
+	    iResultRow.AppendL( TColumn( EColumnTItemId ) );
+	    iResultRow.AppendL( TColumn( EColumnInt32 ) );
+	    iResultRow.AppendL( TColumn( EColumnInt64 ) );
+	    iResultRow.AppendL( TColumn( EColumnInt64 ) );
+	    iResultRow.AppendL( TColumn( EColumnTime ) );
+		}
+	}
+
+// ---------------------------------------------------------------------------
+// AppendSelectEventItemStatementL        SELECT statements for event id query
+// ---------------------------------------------------------------------------
+//
+void CMdSFindSqlClause::AppendSelectEventItemStatementL()
+    {
+	// "SELECT Event + NamespaceId.EventId "
+	iQueryBuf->AppendL( KSelectEventIds );
+	iQueryBuf->AppendL( iNamespaceIdDes );
+	iQueryBuf->AppendL( KDotEventId );
+
+	if( iAppendToResultRow )
+		{
+		// expected result event
+	    iResultRow.AppendL( TColumn( EColumnTItemId ) );
+		}
+    }
+
+// ---------------------------------------------------------------------------
+// AppendSelectRealtionItemStatementL        SELECT statements for Realtion id query
+// ---------------------------------------------------------------------------
+//AppendSelectRelationItemStatementL
+void CMdSFindSqlClause::AppendSelectRealtionItemStatementL()
+    {
+	 //"SELECT Relation.EventId "
+	iQueryBuf->AppendL( KSelectRelationIds );
+    iQueryBuf->AppendL( iNamespaceIdDes );
+    iQueryBuf->AppendL( KDotRelationId );
+	
+	if( iAppendToResultRow )
+		{
+		//expected result relation
+		iResultRow.AppendL( TColumn( EColumnTItemId ) );
+		}
+    }
+
+// ---------------------------------------------------------------------------
+// AppendSelectObjectItemStatementL    SELECT statements for object item query
+// ---------------------------------------------------------------------------
+//
+void CMdSFindSqlClause::AppendSelectObjectItemStatementL()
+	{
+	if( iAppendToResultRow )
+		{
+		// add expected fixed "base" object's columns
+		iResultRow.AppendL( TColumn( EColumnTItemId ) ); // object ID
+		iResultRow.AppendL( TColumn( EColumnTDefId ) ); // object definition ID
+		iResultRow.AppendL( TColumn( EColumnUint32 ) ); // flags
+		iResultRow.AppendL( TColumn( EColumnUint32 ) ); // media ID
+		iResultRow.AppendL( TColumn( EColumnUint32 ) ); // UsageCount
+		iResultRow.AppendL( TColumn( EColumnInt64 ) );  // GUID high
+		iResultRow.AppendL( TColumn( EColumnInt64 ) );  // GUID low
+		iResultRow.AppendL( TColumn( EColumnDes16 ) );  // URI
+		}
+
+	if( iSearchCriteria->iPropertyFilters.iPtr.iCount > 0 )
+		{
+		// "SELECT BO...."
+		iQueryBuf->AppendL( KSelectPropertyFilterBegin );
+
+		const TUint32 position = iSerializedBuffer->Position();
+
+		AppendPropertyFiltersL();
+
+		iSerializedBuffer->PositionL( position );
+		}
+	else
+		{
+		// No property filters so get all properties
+		
+		// "SELECT BO.* "
+		iQueryBuf->AppendL( KSelectAllFromBaseObject );
+	
+		const TInt propCount = iObjectDef->GetAllPropertiesCount();
+		TBool addBaseObjectId = EFalse;
+		
+		if( KBaseObjectDefId != iObjectDef->GetId() )
+			{
+			if( !iSourceObjectDefs )
+				{
+				// ",O.* "
+				iQueryBuf->AppendL( KAllFromObject );
+				}
+			else
+				{
+				// ",O.ObjectId"
+				iQueryBuf->AppendL( KComma );
+				iQueryBuf->AppendL( KObjectObjectId );
+
+				// no filters, so add all property names
+				const TInt lookupObjectPropertyCount = 
+					iObjectDef->GetPropertiesCount();
+				
+				for( TInt i = 0; i < lookupObjectPropertyCount; i++)
+					{
+					iQueryBuf->AppendL( KComma );
+					const CMdsPropertyDef* propDef = iObjectDef->GetProperty( i );
+					iQueryBuf->AppendL( propDef->GetName() );
+					}
+				iQueryBuf->AppendL( KSpace );
+				}
+			addBaseObjectId = ETrue;
+			}
+
+		if (propCount > 0)
+			{
+			// add base object properties, object ID and the rest properties
+			for( TUint32 i = 0; i < propCount; i++ )
+				{
+				const CMdsPropertyDef& propDef = iObjectDef->GetPropertyColumnL( i ).iPropertyDef;
+
+				// add column for object ID when object definition is not "base" object
+				if( addBaseObjectId && KBaseObjectBasicValueColumnOffset < propDef.GetId() )
+					{
+					if( iAppendToResultRow )
+						{
+			    	    // add expected column for object ID
+						iResultRow.AppendL( TColumn( EColumnTItemId ) ); // object ID
+						}
+					addBaseObjectId = EFalse;
+					}
+
+				if( iAppendToResultRow )
+					{
+					// add expected columns	from object
+					iResultRow.AppendL( TColumn( propDef.GetSqlType() ) );
+					}
+				}
+				
+			if( addBaseObjectId )
+				{
+				if( iAppendToResultRow )
+					{
+					// add expected column for object ID
+					iResultRow.AppendL( TColumn( EColumnTItemId ) ); // object ID
+					}
+				}
+			}
+		}
+
+	if( iIncludeFreetexts )
+		{
+		// ",count(D.Word),sum(length(D.Word)) "
+		iQueryBuf->AppendL( KSelectFreeTextCountAndTotalLength );
+
+		if( iAppendToResultRow )
+			{
+			iResultRow.AppendL( TColumn( EColumnUint32 ) );
+			iResultRow.AppendL( TColumn( EColumnUint32 ) );
+			}
+		}
+	}
+
+// ---------------------------------------------------------------------------
+// AppendFromForObjectL           FROM statements for object query
+// ---------------------------------------------------------------------------
+//
+void CMdSFindSqlClause::AppendFromForObjectL()
+	{
+	// "FROM BaseObject" + namespace def id + " AS BO "
+	iQueryBuf->AppendL( KFromBaseObject );
+	iQueryBuf->AppendL( iNamespaceIdDes );
+	iQueryBuf->AppendL( KAsBaseObject );
+
+	// if object definitions is BaseObject
+	if( KBaseObjectDefId != iSourceObjectDef->GetId() )
+		{
+		// "," + object def's table + namespace def id + " AS O ON BO.ObjectId=O.ObjectId "
+        iQueryBuf->AppendL( KComma );
+
+		AppendTableByObjectDefIdL( iSourceObjectDef->GetId() );
+
+        iQueryBuf->AppendL( KAsObjectOnEqual );
+		}
+
+	if( iIncludeFreetexts )
+		{
+		// Append free text join
+		// "LEFT JOIN TextSearchDictionary" + namespace def id + " 
+		// AS D ON D.WordId IN(SELECT WordId FROM TextSearch" + 
+		// namespace def id + " WHERE BO.ObjectId=ObjectId) "
+		iQueryBuf->AppendL( KFreeTextLeftJoinBegin );
+		iQueryBuf->AppendL( iNamespaceIdDes );
+		iQueryBuf->AppendL( KFreeTextLeftJoinMiddle );
+		iQueryBuf->AppendL( iNamespaceIdDes );
+		iQueryBuf->AppendL( KFreeTextLeftJoinEnd );
+		}
+	}
+
+
+// ---------------------------------------------------------------------------
+// AppendFromForObjectL           FROM statements for Event query
+// ---------------------------------------------------------------------------
+//
+void CMdSFindSqlClause::AppendFromForEventL()
+    {
+   	iQueryBuf->AppendL( KFromEvent );
+	iQueryBuf->AppendL( iNamespaceIdDes );
+   	iQueryBuf->AppendL( KSpace );
+    }
+
+// ---------------------------------------------------------------------------
+// AppendFromForRelationL           FROM statements for Relation query
+// ---------------------------------------------------------------------------
+//
+void CMdSFindSqlClause::AppendFromForRelationL()
+    {
+   	iQueryBuf->AppendL( KFromRealtions );
+	iQueryBuf->AppendL( iNamespaceIdDes );
+	iQueryBuf->AppendL( KSpace );
+    }
+
+
+// ---------------------------------------------------------------------------
+// AppendWhereStatementL           WHERE statements for query
+// ---------------------------------------------------------------------------
+//
+void CMdSFindSqlClause::AppendWhereStatementL()
+	{
+	// move position to begin of the root condition
+	iSerializedBuffer->PositionL( iSearchCriteria->iRootCondition );
+
+	const TMdCLogicCondition& condition = TMdCLogicCondition::GetFromBufferL( 
+			*iSerializedBuffer );
+
+	if( EConditionTypeLogic == condition.iConditionType )
+		{
+		// if root condition's child count is more than zero add where statement
+		if( condition.iChildConditions.iPtr.iCount > 0 )
+			{
+			// "WHERE("root condition")"
+			iQueryBuf->AppendL( KWhere );
+
+			if( EQueryTypeObject == iSearchCriteria->iQueryType )
+				{
+				// remove "deleted" objects from result
+				iQueryBuf->AppendL( KGetNotFlagAnd );
+				iVariables.AppendL( TColumn( EMdEObjectFlagRemoved ) );
+
+				if( EUserLevelDeviceAccess != iUserLevel )
+					{
+					if( iIncludeNotPresent )
+						{
+						// If client application doesn't have device capability limit to
+						// only non-confidential (confidential flag is not set)
+						// "(NOT Flags&?)AND "
+						iQueryBuf->AppendL( KGetNotFlagAnd );
+						iVariables.AppendL( TColumn( EMdEObjectFlagConfidential ) );
+						}
+					else
+						{
+						// If client application doesn't have device capability limit to
+						// only non-confidential (confidential flag is not set)
+						// and not present objects
+						// "(NOT Flags&?)AND "
+						iQueryBuf->AppendL( KGetNotFlagAnd );
+						iVariables.AppendL( TColumn( EMdEObjectFlagConfidential | EMdEObjectFlagNotPresent ) );
+						}
+					}
+				else
+					{
+					if( !iIncludeNotPresent )
+						{
+						// Drop not present objects
+						// "(NOT Flags&?)AND "
+						iQueryBuf->AppendL( KGetNotFlagAnd );
+						iVariables.AppendL( TColumn( EMdEObjectFlagNotPresent ) );
+						}
+					}
+				}
+
+			if ( EQueryTypeRelation == iSearchCriteria->iQueryType )
+				{
+				// add "(NOT Flags&?)AND " with not present flag
+				iQueryBuf->AppendL( KGetNotFlagAnd );
+				iVariables.AppendL( TColumn( EMdERelationFlagNotPresent ) );
+				// add "(NOT Flags&?)AND " with deleted flag
+				iQueryBuf->AppendL( KGetNotFlagAnd );
+				iVariables.AppendL( TColumn( EMdERelationFlagDeleted ) );
+				}
+
+			iQueryBuf->AppendL( KLeftBracket );
+
+			// move position to begin of the root condition
+			iSerializedBuffer->PositionL( iSearchCriteria->iRootCondition );
+
+			ConditionStatementL();
+
+			iQueryBuf->AppendL( KRightBracket );
+			}
+		else if( EQueryTypeObject == iSearchCriteria->iQueryType )
+			{
+			// remove "deleted" objects from result
+			iQueryBuf->AppendL( KWhereNotFlag );
+			iVariables.AppendL( TColumn( EMdEObjectFlagRemoved ) );
+
+			if( EUserLevelDeviceAccess != iUserLevel )
+				{
+				if( iIncludeNotPresent )
+					{
+					// If client application doesn't have device capability limit to
+					// only non-confidential (confidential flag is not set)
+					// "WHERE(NOT Flags&?)"
+					iQueryBuf->AppendL( KAnd );
+					iQueryBuf->AppendL( KGetNotFlag );
+					iVariables.AppendL( TColumn( EMdEObjectFlagConfidential ) );
+					}
+				else
+					{
+					// If client application doesn't have device capability limit to
+					// only non-confidential (confidential flag is not set)
+					// and not present objects
+					// "WHERE(NOT Flags&?)"
+					iQueryBuf->AppendL( KAnd );
+					iQueryBuf->AppendL( KGetNotFlag );
+					iVariables.AppendL( TColumn( EMdEObjectFlagConfidential | EMdEObjectFlagNotPresent ) );
+					}
+				}
+			else
+				{
+				if( !iIncludeNotPresent )
+					{
+					// Drop not present objects
+					// "WHERE(NOT Flags&?)"
+					iQueryBuf->AppendL( KAnd );
+					iQueryBuf->AppendL( KGetNotFlag );
+					iVariables.AppendL( TColumn( EMdEObjectFlagNotPresent ) );
+					}
+				}
+			}
+		else if ( EQueryTypeRelation == iSearchCriteria->iQueryType )
+			{
+			// add "WHERE(NOT Flags&?)" with not present flag
+			iQueryBuf->AppendL( KWhereNotFlag );
+			iVariables.AppendL( TColumn( EMdERelationFlagNotPresent ) );
+			// add "AND (NOT Flags&?)" with deleted flag
+			iQueryBuf->AppendL( KAnd );
+			iQueryBuf->AppendL( KGetNotFlag );
+			iVariables.AppendL( TColumn( EMdERelationFlagDeleted ) );
+			}
+		}
+	else
+		{
+		User::Leave( KErrMdEUnknownConditionType );
+		}
+	}
+
+// ---------------------------------------------------------------------------
+// AppendSelectForObjectGroupL      SELECT statements for object query
+// ---------------------------------------------------------------------------
+//
+void CMdSFindSqlClause::AppendSelectForObjectL()
+    {
+    switch( iSearchCriteria->iQueryResultType )
+	    {
+	    case EQueryResultModeCount:
+	        // Format: SELECT count(*) FROM
+	        AppendSelectCountStatementL();
+	        break;
+	    case EQueryResultModeDistinctValues:
+	        // Format: SELECT "wanted property's column" FROM
+	        AppendSelectDistinctStatementL();
+	        break;
+	    case EQueryResultModeItem:
+	    	AppendSelectObjectItemStatementL();
+	    	break;
+	    case EQueryResultModeId:
+	    	AppendSelectObjectIdStatementL();
+	    	break;
+
+	    default:
+	    	{
+#ifdef _DEBUG
+            User::Panic( _L("MdSFCSeO") , KErrMdEUnknownQueryResultMode );
+#endif
+	    	User::Leave( KErrMdEUnknownQueryResultMode );
+	    	}
+	    }
+    }
+
+// ---------------------------------------------------------------------------
+// AppendSelectForRelationGroupL        SELECT statements for relation query
+// ---------------------------------------------------------------------------
+//
+void CMdSFindSqlClause::AppendSelectForRelationL()
+    {
+    switch( iSearchCriteria->iQueryResultType )
+        {
+	    case EQueryResultModeCount:
+	        // Format: SELECT count(*) FROM
+	        AppendSelectCountStatementL();
+	        break;
+	    case EQueryResultModeItem:
+	    	// Format: SELECT * FROM   //  SELECT * FROM Relation
+	    	AppendSelectAllFromRelationStatementL();
+	    	break;
+	    case EQueryResultModeId:
+	    	// SELECT Relation.RelationId FROM // SELECT 
+	    	AppendSelectRealtionItemStatementL();
+	    	break;
+
+	    default:
+	    	{
+#ifdef _DEBUG
+            User::Panic( _L("MdSFCSeR") , KErrMdEUnknownQueryResultMode );
+#endif
+	    	User::Leave( KErrMdEUnknownQueryResultMode );
+	    	}
+        }
+    }
+
+// ---------------------------------------------------------------------------
+// AppendSelectForEventL()       SELECT statements for event query
+// ---------------------------------------------------------------------------
+//
+void CMdSFindSqlClause::AppendSelectForEventL()
+    {
+    switch( iSearchCriteria->iQueryResultType )
+        {
+	    case EQueryResultModeCount:
+	        // Format: SELECT count(*) FROM
+	        AppendSelectCountStatementL();
+	        break;
+	    case EQueryResultModeItem:
+	    	// Format: SELECT * FROM   //  SELECT * FROM Event
+	    	AppendSelectAllFromEventStatementL();
+	    	break;
+	    case EQueryResultModeId:
+	    	// SELECT EventDef.EventId FROM // SELECT EventDef.EventDefId FROM Event
+	    	AppendSelectEventItemStatementL();
+	    	break;
+
+	    default:
+	    	{
+#ifdef _DEBUG
+            User::Panic( _L("MdSFCSeE") , KErrMdEUnknownQueryResultMode );
+#endif	    	
+	    	User::Leave( KErrMdEUnknownQueryResultMode );
+	    	}
+        }
+    }
+
+// ---------------------------------------------------------------------------
+// ConditionStatementL       Recursive parsing of condition statements
+// ---------------------------------------------------------------------------
+//
+void CMdSFindSqlClause::ConditionStatementL(TBool aNegated, TAppendIn aAppendIdIn)
+    {
+    const TMdCCondition& condition = TMdCCondition::GetFromBufferL( *iSerializedBuffer );
+
+    TBool negated = condition.iNegated;
+
+	if( aNegated )
+		{
+		negated = !negated;
+		}
+
+	const TConditionType conditionType = (TConditionType)condition.iConditionType;
+
+	if( aAppendIdIn != EAppendInFalse )
+		{
+		if ( EConditionTypeLogic != conditionType )
+			{
+			if ( aAppendIdIn == EAppendInTrue )
+				{
+				AppendIdInL();
+				}
+			else if (aAppendIdIn == EAppendInRelationLeft)
+				{
+				iQueryBuf->AppendL( KRelationLeftObjectIdIn );
+				}
+			else if (aAppendIdIn == EAppendInRelationRight)
+				{
+				iQueryBuf->AppendL( KRelationRightObjectIdIn );
+				}
+			else
+				{
+#ifdef _DEBUG
+				User::Panic( _L("MdSFCCo1") , KErrCorrupt );
+#endif
+				User::Leave( KErrCorrupt );
+				}
+			}
+
+		// Add recursive child criteria surrounded by "("child")".
+		iQueryBuf->AppendL( KLeftBracket );
+		}
+
+	switch( conditionType )
+		{
+		case EConditionTypeLogic:
+			AppendLogicConditionL( negated, aAppendIdIn );
+			break;
+		case EConditionTypeObject:
+			AppendObjectConditionL( negated );
+			break;
+		case EConditionTypeProperty:
+			AppendPropertyConditionL( negated );
+			break;
+		case EConditionTypePropertyIntRange:
+		case EConditionTypePropertyInt64Range:
+		case EConditionTypePropertyUintRange:
+		case EConditionTypePropertyRealRange:
+		case EConditionTypePropertyTimeRange:
+			AppendPropertyRangeConditionL( negated );
+			break;
+		case EConditionTypePropertyText:
+			AppendPropertyTextConditionL( negated );
+			break;
+		case EConditionTypePropertyBool:
+			AppendPropertyBoolConditionL( negated );
+			break;
+		case EConditionTypeRelation:
+			AppendRelationConditionL( negated );
+			break;
+		case EConditionTypeEvent:
+			AppendEventConditionL( negated );
+			break;
+		default: // Unknown condition type
+#ifdef _DEBUG
+            User::Panic( _L("MdSFCCo2") , KErrMdEUnknownConditionType );
+#endif
+			User::Leave( KErrMdEUnknownConditionType );
+		}
+
+	if( aAppendIdIn )
+		{		
+		iQueryBuf->AppendL( KRightBracket );
+		}
+    }
+
+// ---------------------------------------------------------------------------
+// AppendObjectId        Help method for appending object ID clause.
+// ---------------------------------------------------------------------------
+//
+void CMdSFindSqlClause::AppendObjectIdL()
+	{
+	if( KBaseObjectDefId == iObjectDef->GetId() )
+		{
+		// "BO.ObjectId"
+		iQueryBuf->AppendL( KBaseObjectObjectId );
+		}
+	else
+		{
+		// "O.ObjectId"
+		iQueryBuf->AppendL( KObjectObjectId );
+		}
+	}
+
+// ---------------------------------------------------------------------------
+// AppendIdIn                    			Help method for appending object, 
+//											event or relation ID IN clause.
+// ---------------------------------------------------------------------------
+//
+void CMdSFindSqlClause::AppendIdInL()
+	{
+	switch( iSearchCriteria->iQueryType )
+		{
+		case EQueryTypeObject:
+			// "BO.ObjectId" or "O.ObjectId"
+			AppendObjectIdL();
+			break;
+		case EQueryTypeRelation:
+			iQueryBuf->AppendL( KRelationId );
+			break;
+		case EQueryTypeEvent:
+			iQueryBuf->AppendL( KEventId );
+			break;
+		default:
+#ifdef _DEBUG
+            User::Panic( _L("MdSFCAII") , KErrMdEUnknownQueryType );
+#endif
+			User::Leave( KErrMdEUnknownQueryType );
+		}
+
+	// " IN"
+	iQueryBuf->AppendL( KIn );
+	}
+
+
+// ---------------------------------------------------------------------------
+// AppendLogicConditionL        Help method for appending logic condition.
+// ---------------------------------------------------------------------------
+//
+void CMdSFindSqlClause::AppendLogicConditionL(TBool aNegated, TAppendIn aAppendIdIn)
+	{
+	const TMdCLogicCondition& condition = TMdCLogicCondition::GetFromBufferL( 
+			*iSerializedBuffer );
+
+    // Add recursive all children.
+    for( TUint32 i = 0; i < condition.iChildConditions.iPtr.iCount; i++)
+		{
+		// get offset and move position to begin of child condition
+		iSerializedBuffer->PositionL( condition.iChildConditions.iPtr.iOffset + 
+				CMdCSerializationBuffer::KRequiredSizeForTUint32 * i );
+
+		TUint32 childOffset;
+		iSerializedBuffer->ReceiveL( childOffset );
+
+		iSerializedBuffer->PositionL( childOffset );
+
+		// If not first add operator
+		if( i > 0 )
+			{
+			switch( condition.iOperator )
+				{
+				case ELogicConditionOperatorAnd:
+					iQueryBuf->AppendL( KAnd );
+					break;
+				case ELogicConditionOperatorOr:
+					iQueryBuf->AppendL( KOr );
+					break;
+				default:
+#ifdef _DEBUG
+					User::Panic( _L("MdSFCALC") , KErrMdEUnknownConditionCompareMethod );
+#endif
+					User::Leave( KErrMdEUnknownConditionCompareMethod ); 
+				}
+			}
+
+		ConditionStatementL( aNegated, aAppendIdIn );
+		}
+	}
+
+// ---------------------------------------------------------------------------
+// AppendObjectConditionL        Help method for appending object condition.
+// ---------------------------------------------------------------------------
+//
+void CMdSFindSqlClause::AppendObjectConditionL(TBool aNegated)
+	{
+	const TMdCObjectCondition& condition = TMdCObjectCondition::GetFromBufferL( 
+			*iSerializedBuffer );
+
+	// "SELECT ObjectId FROM BaseObject"namespace def ID" WHERE(...)"
+	iQueryBuf->AppendL( KSelectObjectIdFromBaseObject );
+	iQueryBuf->AppendL( iNamespaceIdDes );
+	iQueryBuf->AppendL( KSpace );
+	iQueryBuf->AppendL( KWhere );
+
+	iQueryBuf->AppendL( KLeftBracket );
+
+	// remove "deleted" objects from result
+	iQueryBuf->AppendL( KGetNotFlagAnd );
+	iVariables.AppendL( TColumn( EMdEObjectFlagRemoved ) );
+	
+   if( iPlaceholdersOnly )
+        {
+        // Drop non-placeholder  objects
+        // "(Flags&?)AND "
+        iQueryBuf->AppendL( KGetFlagAnd );
+        iVariables.AppendL( TColumn( EMdEObjectFlagPlaceholder ) );
+        }
+
+	if( EUserLevelDeviceAccess == iUserLevel )
+		{
+		switch( condition.iConfidentialityLevel )
+			{
+			// Only non-confidential (confidential flag is not set)
+			// "(NOT Flags&?)AND "
+			case EObjectConditionLevelNormal:
+				iQueryBuf->AppendL( KGetNotFlagAnd );
+				iVariables.AppendL( TColumn( EMdEObjectFlagConfidential ) );
+				break;
+			// Only confidential (confidential flag is set)
+			// "(Flags&?)AND "
+			case EObjectConditionLevelConfidential:
+				iQueryBuf->AppendL( KGetFlagAnd );
+				iVariables.AppendL( TColumn( EMdEObjectFlagConfidential ) );
+				break;
+
+			case EObjectConditionLevelIgnoreConfidentiality:
+				// no implementation needed
+				break;
+
+		    default:
+		    	{
+#ifdef _DEBUG
+				User::Panic( _L("MdSFCAO1") , KErrMdEUnknownConfidentialityLevel );
+#endif
+		    	User::Leave( KErrMdEUnknownConfidentialityLevel );
+		    	}
+			}
+		}
+	else
+		{
+		// If client application doesn't have device capability limit to
+		// only non-confidential (confidential flag is not set)
+		// "(NOT Flags&?)AND "
+		iQueryBuf->AppendL( KGetNotFlagAnd );
+		iVariables.AppendL( TColumn( EMdEObjectFlagConfidential ) );
+		}
+
+	if( ( condition.iFlags & EMdEObjectFlagNotPresent ) == EFalse )
+		{
+		// Not present flag is not set
+		// "NOT(Flags&?)AND "
+		iQueryBuf->AppendL( KGetNotFlagAnd );
+		iVariables.AppendL( TColumn( EMdEObjectFlagNotPresent ) );
+		}
+
+	if( ( condition.iFlags & EMdEObjectFlagPlaceholder ) )
+		{
+		// Placeholder flag is not set
+		// "NOT(Flags&?)AND "
+		iQueryBuf->AppendL( KGetNotFlagAnd );
+		iVariables.AppendL( TColumn( EMdEObjectFlagPlaceholder ) );
+		}
+
+	if( aNegated )
+		{
+		// "NOT "
+		iQueryBuf->AppendL( KNotWithSpace );
+		}
+
+	// move position to begin of compare condition
+	iSerializedBuffer->PositionL( condition.iCondition );
+
+	switch( condition.iCompareMethod )
+		{
+		case EObjectConditionCompareNone:
+			break;
+		case EObjectConditionCompareId:
+			{
+			TItemId objectId;
+			iSerializedBuffer->ReceiveL( objectId );
+
+			iQueryBuf->AppendL( KObjectIdEqual );
+			iVariables.AppendL( TColumn( objectId ) );
+			}
+			break;
+		case EObjectConditionCompareIds:
+			{
+			TInt32 objectIdCount;
+			iSerializedBuffer->ReceiveL( objectIdCount );
+
+			if( objectIdCount == 1 )
+				{
+				TItemId objectId;
+				iSerializedBuffer->ReceiveL( objectId );
+
+				iQueryBuf->AppendL( KObjectIdEqual );
+				iVariables.AppendL( TColumn( objectId ) );
+				}
+			else if( objectIdCount > 1 )
+				{
+				iQueryBuf->AppendL( KObjectIdIn );
+				iQueryBuf->AppendL( KLeftBracket );
+
+				TItemId objectId;
+				iSerializedBuffer->ReceiveL( objectId );
+
+				iQueryBuf->AppendL( KVariable );
+				iVariables.AppendL( TColumn( objectId ) );
+
+				for( TInt32 i = 1; i < objectIdCount; i++ )
+					{
+					iSerializedBuffer->ReceiveL( objectId );
+
+					iQueryBuf->AppendL( KCommaVariable );
+					iVariables.AppendL( TColumn( objectId ) );
+					}
+
+				iQueryBuf->AppendL( KRightBracket );
+				}
+			}
+			break;
+		case EObjectConditionCompareGuid:
+			{
+			TInt64 guidHigh;
+			iSerializedBuffer->ReceiveL( guidHigh );			
+			TInt64 guidLow;
+			iSerializedBuffer->ReceiveL( guidLow );			
+
+			iQueryBuf->AppendL( KObjectGuidEqual );
+			iVariables.AppendL( TColumn( guidHigh ) );
+			iVariables.AppendL( TColumn( guidLow ) );
+			}
+			break;
+		case EObjectConditionCompareObjectDef:
+			{
+			TDefId objectDefId;
+			iSerializedBuffer->ReceiveL( objectDefId );
+
+			iQueryBuf->AppendL( KObjectDefIdEqual );
+			iVariables.AppendL( TColumn( objectDefId ) );
+			}
+			break;
+		case EObjectConditionCompareUsageCount:
+			{
+			iQueryBuf->AppendL( KObjectUsageCount );
+			AppendRangeL( EUint32RangeValue );
+			}
+			break;
+		case EObjectConditionCompareUri:
+			{
+			TPtrC16 uriPtr = iSerializedBuffer->ReceivePtr16L();
+
+			iQueryBuf->AppendL( KObjectUriEqual );
+			iVariables.AppendL( TColumn( uriPtr ) );
+			}
+			break;
+		case EObjectConditionCompareUriBeginsWith:
+			{
+			TPtrC16 uriPtr = iSerializedBuffer->ReceivePtr16L();
+
+			HBufC16* pattern = HBufC16::NewLC( uriPtr.Length() + 1 );  // prepare for uri%
+
+	        TPtr16 modPattern = pattern->Des();
+
+			// add wildcard after URI "uri%"
+			modPattern.Append( uriPtr );
+			modPattern.Append( KWildcard );
+
+			iVariables.AppendL( TColumn( pattern ) );
+
+			CleanupStack::Pop( pattern );
+
+			iQueryBuf->AppendL( KObjectUriBeginsWith );			
+			}
+			break;
+		case EObjectConditionCompareFreeText:
+			{
+			TPtrC16 freetextPtr = iSerializedBuffer->ReceivePtr16L();
+
+			HBufC* freetext = freetextPtr.AllocLC();
+			iFreeText.AppendL( freetext );
+			CleanupStack::Pop( freetext );
+
+			iQueryBuf->AppendL( KObjectFreeTextSearchStart );
+			iQueryBuf->AppendL( iNamespaceIdDes );
+			iQueryBuf->AppendL( KObjectFreeTextSearchWhere );
+			iQueryBuf->AppendL( iNamespaceIdDes );
+			iQueryBuf->AppendL( KObjectFreeTextSearchDictionaryWhere );
+			iQueryBuf->AppendL( KEqual );
+			iQueryBuf->AppendL( KObjectFreeTextSearchEnd );
+			iVariables.AppendL( TColumn( freetextPtr ) );
+			}
+			break;
+		case EObjectConditionCompareFreeTextContains:
+			{
+			TPtrC16 freetextPtr = iSerializedBuffer->ReceivePtr16L();
+
+			HBufC* freetext = freetextPtr.AllocLC();
+			iFreeText.AppendL( freetext );
+			CleanupStack::Pop( freetext );
+
+			iQueryBuf->AppendL( KObjectFreeTextSearchStart );
+			iQueryBuf->AppendL( iNamespaceIdDes );
+			iQueryBuf->AppendL( KObjectFreeTextSearchWhere );
+			iQueryBuf->AppendL( iNamespaceIdDes );
+			iQueryBuf->AppendL( KObjectFreeTextSearchDictionaryWhere );
+			
+			HBufC16* pattern = HBufC16::NewLC( freetextPtr.Length() + 2 );  // prepare for %freetext%
+
+	        TPtr16 modPattern = pattern->Des();
+
+			// add wildcard before and after freetext "%freetext%"
+			modPattern.Append( KWildcard );
+			modPattern.Append( freetextPtr );
+			modPattern.Append( KWildcard );
+
+			iVariables.AppendL( TColumn( pattern ) );
+
+			CleanupStack::Pop( pattern );
+
+			iQueryBuf->AppendL( KLike );
+
+			iQueryBuf->AppendL( KObjectFreeTextSearchEnd );
+			}
+			break;
+		case EObjectConditionCompareFreeTextBeginsWith:
+			{
+			TPtrC16 freetextPtr = iSerializedBuffer->ReceivePtr16L();
+
+			HBufC* freetext = freetextPtr.AllocLC();
+			iFreeText.AppendL( freetext );
+			CleanupStack::Pop( freetext );
+
+			iQueryBuf->AppendL( KObjectFreeTextSearchStart );
+			iQueryBuf->AppendL( iNamespaceIdDes );
+			iQueryBuf->AppendL( KObjectFreeTextSearchWhere );
+			iQueryBuf->AppendL( iNamespaceIdDes );
+			iQueryBuf->AppendL( KObjectFreeTextSearchDictionaryWhere );
+
+			HBufC16* pattern = HBufC16::NewLC( freetextPtr.Length() + 1 );  // prepare for freetext%
+
+	        TPtr16 modPattern = pattern->Des();
+
+			// add wildcard after freetext "freetext%"
+			modPattern.Append( freetextPtr );
+			modPattern.Append( KWildcard );
+
+			iVariables.AppendL( TColumn( pattern ) );
+
+			CleanupStack::Pop( pattern );
+
+			iQueryBuf->AppendL( KLike );
+
+			iQueryBuf->AppendL( KObjectFreeTextSearchEnd );
+			}
+			break;
+		case EObjectConditionCompareFreeTextEndsWith:
+			{
+			TPtrC16 freetextPtr = iSerializedBuffer->ReceivePtr16L();
+
+			HBufC* freetext = freetextPtr.AllocLC();
+			iFreeText.AppendL( freetext );
+			CleanupStack::Pop( freetext );
+
+			iQueryBuf->AppendL( KObjectFreeTextSearchStart );
+			iQueryBuf->AppendL( iNamespaceIdDes );
+			iQueryBuf->AppendL( KObjectFreeTextSearchWhere );
+			iQueryBuf->AppendL( iNamespaceIdDes );
+			iQueryBuf->AppendL( KObjectFreeTextSearchDictionaryWhere );
+
+			HBufC16* pattern = HBufC16::NewLC( freetextPtr.Length() + 1 );  // prepare for %freetext
+
+	        TPtr16 modPattern = pattern->Des();
+
+			// add wildcard before freetext "%freetext"
+			modPattern.Append( KWildcard );
+			modPattern.Append( freetextPtr );
+
+			iVariables.AppendL( TColumn( pattern ) );
+
+			CleanupStack::Pop( pattern );
+
+			iQueryBuf->AppendL( KLike );
+
+			iQueryBuf->AppendL( KObjectFreeTextSearchEnd );
+			}
+			break;
+		default:
+#ifdef _DEBUG
+			User::Panic( _L("MdSFCAO2") , KErrMdEUnknownConditionCompareMethod );
+#endif
+			User::Leave( KErrMdEUnknownConditionCompareMethod );
+		}
+
+	iQueryBuf->AppendL( KRightBracket );
+	}
+
+// ---------------------------------------------------------------------------
+// AppendRangeL                    Help method for appending range.
+// ---------------------------------------------------------------------------
+//
+void CMdSFindSqlClause::AppendRangeL(TRangeValueType aRangeValueType)
+	{
+	TInt32 rangeTypeValue;
+	iSerializedBuffer->ReceiveL( rangeTypeValue );
+	const TMdERangeType rangeType = (TMdERangeType)rangeTypeValue;
+
+	TMdCValueUnion minValue;
+	iSerializedBuffer->ReceiveL( minValue );
+
+	TMdCValueUnion maxValue;
+	iSerializedBuffer->ReceiveL( maxValue );
+
+	TInt64 minIntegerValue = KMaxTInt64;
+	TInt64 maxIntegerValue = 0;
+
+	switch( aRangeValueType )
+		{
+		case EInt32RangeValue:
+			minIntegerValue = maxValue.iInt32;
+			maxIntegerValue = maxValue.iInt32;
+			break;
+		case EUint32RangeValue:
+			minIntegerValue = maxValue.iUint32;
+			maxIntegerValue = maxValue.iUint32;
+			break;
+		case EInt64RangeValue:
+			minIntegerValue = maxValue.iInt64;
+			maxIntegerValue = maxValue.iInt64;
+			break;
+		default:		
+		    break;
+		}
+	
+	switch( rangeType )
+		{
+		case EMdERangeTypeAny:
+			break;
+		case EMdERangeTypeEqual:
+			iQueryBuf->AppendL( KEqual );
+			iVariables.AppendL( TColumn( minIntegerValue ) );
+			break;
+		case EMdERangeTypeNotEqual:
+			iQueryBuf->AppendL( KNotEqual );
+			iVariables.AppendL( TColumn( minIntegerValue ) );
+			break;
+		case EMdERangeTypeLess:
+			iQueryBuf->AppendL( KLess );
+			iVariables.AppendL( TColumn( maxIntegerValue ) );
+			break;
+		case EMdERangeTypeLessOrEqual:
+			iQueryBuf->AppendL( KLessOrEqual );
+			iVariables.AppendL( TColumn( maxIntegerValue ) );
+			break;
+		case EMdERangeTypeGreater:
+			iQueryBuf->AppendL( KGreater );
+			iVariables.AppendL( TColumn( minIntegerValue ) );
+			break;
+		case EMdERangeTypeGreaterOrEqual:
+			iQueryBuf->AppendL( KGreaterOrEqual );
+			iVariables.AppendL( TColumn( minIntegerValue ) );
+			break;
+		case EMdERangeTypeBetween:
+			iQueryBuf->AppendL( KBetween );
+			iVariables.AppendL( TColumn( minIntegerValue ) );
+			iVariables.AppendL( TColumn( maxIntegerValue ) );
+			break;
+		case EMdERangeTypeNotBetween:
+			iQueryBuf->AppendL( KNotBetween );
+			iVariables.AppendL( TColumn( minIntegerValue ) );
+			iVariables.AppendL( TColumn( maxIntegerValue ) );
+			break;
+		default:
+#ifdef _DEBUG
+			User::Panic( _L("MdSFCARa") , KErrMdEUnknownRangeType );
+#endif
+			User::Leave( KErrMdEUnknownRangeType );
+		}
+	}
+
+// ---------------------------------------------------------------------------
+// AppendPropertyConditionL      Help method for appending property condition.
+// ---------------------------------------------------------------------------
+//
+void CMdSFindSqlClause::AppendPropertyConditionL(TBool aNegated)
+	{
+	const TMdCPropertyCondition& condition = 
+		TMdCPropertyCondition::GetFromBufferL( *iSerializedBuffer );
+	
+	// "SELECT ObjectId FROM "
+	iQueryBuf->AppendL( KSelectObjectIdFrom );
+
+	TDefId objectDefId = condition.iObjectDefId;
+
+	// get object def ID for source object def if 
+	// condition is not from "Object" def and 
+	// (not multi object query or (multi object query and WHERE to search from 
+	// doesn't match with WHAT to search))
+	if( KBaseObjectDefId != objectDefId && ( !iSourceObjectDefs || 
+			( iSourceObjectDefs && iObjectDef != iSourceObjectDef ) ) )
+		{
+		objectDefId = iSourceObjectDef->GetId();
+		}
+	AppendTableByObjectDefIdL( objectDefId );
+
+	// "WHERE(...)"
+	iQueryBuf->AppendL( KSpace );
+	iQueryBuf->AppendL( KWhere );
+
+	iQueryBuf->AppendL( KLeftBracket );
+
+	AppendColumnByPropertyDefIdL( condition.iPropertyDefId );
+
+	if( aNegated )
+		{
+		// If negated search objects without specified property
+
+		// " ISNULL"
+		iQueryBuf->AppendL( KIsNull );
+		}
+	else
+		{
+		// " NOTNULL"
+		iQueryBuf->AppendL( KNotNull );
+		}
+
+	iQueryBuf->AppendL( KRightBracket );
+	}
+
+// ---------------------------------------------------------------------------
+// ObjectDefForPropertyCondition        Helper method for getting object 
+//                                      definition for property condition.
+// ---------------------------------------------------------------------------
+//
+TDefId CMdSFindSqlClause::ObjectDefForPropertyCondition(TDefId aObjectDefId)
+	{
+	// if object def is not base object def
+	if( KBaseObjectDefId != aObjectDefId )
+		{
+		const CMdsObjectDef* parent = iSourceObjectDef->GetParent();
+
+		// check if property's object def belongs to 
+		// any of source object def's parents
+		while( parent )
+			{
+			// if property's object def belongs to 
+			// any parent, use source object def's ID
+			if( aObjectDefId == parent->GetId() )
+				{
+				return iSourceObjectDef->GetId();
+				}
+
+			// get parent's parent
+			parent = parent->GetParent();
+			}
+		}
+
+	return aObjectDefId;
+	}
+
+// ---------------------------------------------------------------------------
+// AppendPropertyRangeConditionL        Help method for appending property 
+//                                      range condition.
+// ---------------------------------------------------------------------------
+//
+void CMdSFindSqlClause::AppendPropertyRangeConditionL(TBool aNegated)
+	{
+	const TMdCPropertyCondition& condition = 
+		TMdCPropertyCondition::GetFromBufferL( *iSerializedBuffer );
+
+	// "SELECT ObjectId FROM "
+	iQueryBuf->AppendL( KSelectObjectIdFrom );
+
+	TDefId objectDefId = ObjectDefForPropertyCondition( 
+			condition.iObjectDefId );
+
+	AppendTableByObjectDefIdL( objectDefId );
+
+	// "WHERE(...)"
+	iQueryBuf->AppendL( KSpace );
+	iQueryBuf->AppendL( KWhere );
+
+	iQueryBuf->AppendL( KLeftBracket );
+
+	if( aNegated )
+		{
+		// "NOT "
+		iQueryBuf->AppendL( KNotWithSpace );
+		}
+
+	AppendColumnByPropertyDefIdL( condition.iPropertyDefId, objectDefId );
+
+	// move position to begin of compare condition
+	iSerializedBuffer->PositionL( condition.iCondition );
+	
+	TInt32 rangeTypeValue;
+	iSerializedBuffer->ReceiveL( rangeTypeValue );
+	const TMdERangeType rangeType = (TMdERangeType)rangeTypeValue;
+
+	TMdCValueUnion minValue;
+	iSerializedBuffer->ReceiveL( minValue );
+
+	TMdCValueUnion maxValue;
+	iSerializedBuffer->ReceiveL( maxValue );
+
+	TBool integerValue = ETrue;
+	TInt64 minIntegerValue = 0;
+	TInt64 maxIntegerValue = 0;
+
+	// get correct value and value's type
+	switch( condition.iConditionType )
+	{
+		case EConditionTypePropertyIntRange:
+			minIntegerValue = minValue.iInt32;
+			maxIntegerValue = maxValue.iInt32;
+			break;
+		case EConditionTypePropertyUintRange:
+			minIntegerValue = minValue.iUint32;
+			maxIntegerValue = maxValue.iUint32;
+			break;
+		case EConditionTypePropertyInt64Range:
+		case EConditionTypePropertyTimeRange:
+			minIntegerValue = minValue.iInt64;
+			maxIntegerValue = maxValue.iInt64;
+			break;
+		case EConditionTypePropertyRealRange:
+			integerValue = EFalse;
+			break;
+		default:
+#ifdef _DEBUG
+			User::Panic( _L( "MdSFCAR1" ), KErrMdEUnknownConditionType );
+#endif
+			User::Leave( KErrMdEUnknownConditionType );
+			break;
+	};
+	
+	switch( rangeType )
+		{
+		case EMdERangeTypeAny:
+			break;
+		case EMdERangeTypeEqual:
+			iQueryBuf->AppendL( KEqual );
+			if( integerValue )
+				{
+				iVariables.AppendL( TColumn( minIntegerValue ) );
+				}
+			else
+				{
+				iVariables.AppendL( TColumn( minValue.iReal ) );
+				}
+			break;
+		case EMdERangeTypeNotEqual:
+			iQueryBuf->AppendL( KNotEqual );
+			if( integerValue )
+				{
+				iVariables.AppendL( TColumn( minIntegerValue ) );
+				}
+			else
+				{
+				iVariables.AppendL( TColumn( minValue.iReal ) );
+				}
+
+			break;
+		case EMdERangeTypeLess:
+			iQueryBuf->AppendL( KLess );
+			if( integerValue )
+				{
+				iVariables.AppendL( TColumn( maxIntegerValue ) );
+				}
+			else
+				{
+				iVariables.AppendL( TColumn( maxValue.iReal ) );
+				}
+			break;
+		case EMdERangeTypeLessOrEqual:
+			iQueryBuf->AppendL( KLessOrEqual );
+			if( integerValue )
+				{
+				iVariables.AppendL( TColumn( maxIntegerValue ) );
+				}
+			else
+				{
+				iVariables.AppendL( TColumn( maxValue.iReal ) );
+				}
+			break;
+		case EMdERangeTypeGreater:
+			iQueryBuf->AppendL( KGreater );
+			if( integerValue )
+				{
+				iVariables.AppendL( TColumn( minIntegerValue ) );
+				}
+			else
+				{
+				iVariables.AppendL( TColumn( minValue.iReal ) );
+				}
+			break;
+		case EMdERangeTypeGreaterOrEqual:
+			iQueryBuf->AppendL( KGreaterOrEqual );
+			if( integerValue )
+				{
+				iVariables.AppendL( TColumn( minIntegerValue ) );
+				}
+			else
+				{
+				iVariables.AppendL( TColumn( minValue.iReal ) );
+				}
+			break;
+		case EMdERangeTypeBetween:
+			iQueryBuf->AppendL( KBetween );
+			if( integerValue )
+				{
+				iVariables.AppendL( TColumn( minIntegerValue ) );
+				iVariables.AppendL( TColumn( maxIntegerValue ) );
+				}
+			else
+				{
+				iVariables.AppendL( TColumn( minValue.iReal ) );
+				iVariables.AppendL( TColumn( maxValue.iReal ) );
+				}
+			break;
+		case EMdERangeTypeNotBetween:
+			iQueryBuf->AppendL( KNotBetween );
+			if( integerValue )
+				{
+				iVariables.AppendL( TColumn( minIntegerValue ) );
+				iVariables.AppendL( TColumn( maxIntegerValue ) );
+				}
+			else
+				{
+				iVariables.AppendL( TColumn( minValue.iReal ) );
+				iVariables.AppendL( TColumn( maxValue.iReal ) );
+				}
+			break;
+		default:
+#ifdef _DEBUG
+			User::Panic( _L( "MdSFCAR2" ), KErrMdEUnknownRangeType );
+#endif
+			User::Leave( KErrMdEUnknownRangeType );
+		}
+
+	iQueryBuf->AppendL( KRightBracket );
+	}
+
+// ---------------------------------------------------------------------------
+// AppendPropertyTextConditionL            Help method for appending property 
+//                                         text condition.
+// ---------------------------------------------------------------------------
+//
+void CMdSFindSqlClause::AppendPropertyTextConditionL(TBool aNegated)
+	{
+	const TMdCPropertyCondition& condition = 
+		TMdCPropertyCondition::GetFromBufferL( *iSerializedBuffer );
+
+	// "SELECT ObjectId FROM "
+	iQueryBuf->AppendL( KSelectObjectIdFrom );
+
+	TDefId objectDefId = ObjectDefForPropertyCondition( 
+			condition.iObjectDefId );
+
+	AppendTableByObjectDefIdL( objectDefId );
+
+	// "WHERE(...)"
+	iQueryBuf->AppendL( KSpace );
+	iQueryBuf->AppendL( KWhere );
+
+	iQueryBuf->AppendL( KLeftBracket );
+
+	if( aNegated )
+		{
+		// "NOT "
+		iQueryBuf->AppendL( KNotWithSpace );
+		}
+
+	AppendColumnByPropertyDefIdL( condition.iPropertyDefId );
+
+	// move position to begin of compare condition
+	iSerializedBuffer->PositionL( condition.iCondition );
+
+	TUint32 compareMethodValue;
+	iSerializedBuffer->ReceiveL( compareMethodValue );
+	const TTextPropertyConditionCompareMethod compareMethod = 
+		(TTextPropertyConditionCompareMethod)compareMethodValue;
+
+	TPtrC16 textPtr = iSerializedBuffer->ReceivePtr16L();
+
+	switch( compareMethod )
+		{
+		case ETextPropertyConditionCompareEquals:
+			iQueryBuf->AppendL( KEqual );
+			iVariables.AppendL( TColumn( textPtr ) );
+			break;
+		case ETextPropertyConditionCompareContains:
+			{
+			HBufC16* pattern = HBufC16::NewLC( textPtr.Length() + 2 );  // prepare for %text%
+
+	        TPtr16 modPattern = pattern->Des();
+
+			// add wildcard before and after text "%text%"
+			modPattern.Append( KWildcard );
+			modPattern.Append( textPtr );
+			modPattern.Append( KWildcard );
+
+			iVariables.AppendL( TColumn( pattern ) );
+
+			CleanupStack::Pop( pattern );
+
+			iQueryBuf->AppendL( KLike );
+			}
+			break;
+		case ETextPropertyConditionCompareBeginsWith:
+			{
+			HBufC16* pattern = HBufC16::NewLC( textPtr.Length() + 1 );  // prepare for text%
+
+	        TPtr16 modPattern = pattern->Des();
+
+			// add wildcard after text "text%"
+			modPattern.Append( textPtr );
+			modPattern.Append( KWildcard );
+
+			iVariables.AppendL( TColumn( pattern ) );
+
+			CleanupStack::Pop( pattern );
+
+			iQueryBuf->AppendL( KLike );
+			}
+			break;
+		case ETextPropertyConditionCompareEndsWith:
+			{
+			HBufC16* pattern = HBufC16::NewLC( textPtr.Length() + 1 );  // prepare for %text
+
+	        TPtr16 modPattern = pattern->Des();
+
+			// add wildcard before text "%text"
+			modPattern.Append( KWildcard );
+			modPattern.Append( textPtr );
+
+			iVariables.AppendL( TColumn( pattern ) );
+
+			CleanupStack::Pop( pattern );
+
+			iQueryBuf->AppendL( KLike );
+			}
+			break;
+		default:
+#ifdef _DEBUG
+			User::Panic( _L( "MdSFCATC" ), KErrMdEUnknownConditionCompareMethod );
+#endif
+			User::Leave( KErrMdEUnknownConditionCompareMethod );
+		}
+
+	iQueryBuf->AppendL( KRightBracket );
+	}
+
+// ---------------------------------------------------------------------------
+// AppendPropertyBoolConditionL            Help method for appending property 
+//                                         bool condition.
+// ---------------------------------------------------------------------------
+//
+void CMdSFindSqlClause::AppendPropertyBoolConditionL(TBool aNegated)
+	{
+	const TMdCPropertyCondition& condition = 
+		TMdCPropertyCondition::GetFromBufferL( *iSerializedBuffer );
+
+	// "SELECT ObjectId FROM "
+	iQueryBuf->AppendL( KSelectObjectIdFrom );
+
+	TDefId objectDefId = ObjectDefForPropertyCondition( 
+			condition.iObjectDefId );
+
+	AppendTableByObjectDefIdL( objectDefId );
+
+	// "WHERE(...)"
+	iQueryBuf->AppendL( KSpace );
+	iQueryBuf->AppendL( KWhere );
+
+	iQueryBuf->AppendL( KLeftBracket );
+
+	if( aNegated )
+		{
+		// "NOT "
+		iQueryBuf->AppendL( KNotWithSpace );
+		}
+
+	AppendColumnByPropertyDefIdL( condition.iPropertyDefId );
+
+	// move position to begin of compare condition
+	iSerializedBuffer->PositionL( condition.iCondition );
+	
+	TBool boolValue;
+	iSerializedBuffer->ReceiveL( boolValue );
+
+	iQueryBuf->AppendL( KEqual );
+	iVariables.AppendL( TColumn( boolValue ) );
+
+	iQueryBuf->AppendL( KRightBracket );
+	}
+
+// ---------------------------------------------------------------------------
+// AppendEventConditionL                   Help method for appending event 
+//                                         condition for object query.
+// ---------------------------------------------------------------------------
+//
+void CMdSFindSqlClause::AppendEventConditionL(TBool aNegated)
+	{
+	const TMdCEventCondition& condition = TMdCEventCondition::GetFromBufferL( 
+			*iSerializedBuffer );
+
+	if( EQueryTypeEvent == iSearchCriteria->iQueryType )
+		{
+		// "SELECT EventId FROM Event"
+		iQueryBuf->AppendL( KSelectEventIdFromEvent );
+		}
+	else
+		{
+		// "SELECT ObjectId FROM Event"
+		iQueryBuf->AppendL( KSelectObjectIdFromEvent );
+		}
+
+	// ""namespace def ID" WHERE"
+	iQueryBuf->AppendL( iNamespaceIdDes );
+	iQueryBuf->AppendL( KSpace ); 
+	iQueryBuf->AppendL( KWhere );
+
+	// " NOT"
+	if( aNegated )
+		{
+		iQueryBuf->AppendL( KSpaceWithNot );
+		}
+
+	iQueryBuf->AppendL( KLeftBracket );
+
+	TBool firstEventCondition = ETrue;
+
+	if( condition.iEventId != KNoId )
+		{
+		firstEventCondition = EFalse;
+
+		// "EventId="eventId""
+		iQueryBuf->AppendL( KEventIdEqual );
+		iVariables.AppendL( TColumn( condition.iEventId ) );
+		}
+
+	if( condition.iEventDefId != KNoDefId )
+		{
+		if( firstEventCondition == EFalse )
+			{
+			iQueryBuf->AppendL( KSpace );
+			iQueryBuf->AppendL( KAnd );
+			}
+		firstEventCondition = EFalse;
+
+		// "EventDefId="eventDefId""
+		iQueryBuf->AppendL( KEventDefIdEqual );
+		iVariables.AppendL( TColumn( condition.iEventDefId ) );
+		}
+
+	if( condition.iCreationTimeRange != KNoOffset )
+		{
+		if( firstEventCondition == EFalse )
+			{
+			iQueryBuf->AppendL( KSpace );
+			iQueryBuf->AppendL( KAnd );
+			}
+		firstEventCondition = EFalse;
+
+		// "TimeStamp"
+		iQueryBuf->AppendL( KEventTimeStamp );
+		iSerializedBuffer->PositionL( condition.iCreationTimeRange );		
+		AppendRangeL( EInt64RangeValue );
+		}
+
+	if( condition.iObjectCondition != KNoOffset )
+		{
+		if( firstEventCondition == EFalse )
+			{
+			iQueryBuf->AppendL( KSpace );
+			iQueryBuf->AppendL( KAnd );
+			}
+		firstEventCondition = EFalse;
+
+		iQueryBuf->AppendL( KEventObjectIdIn );
+		iSerializedBuffer->PositionL( condition.iObjectCondition );		
+		iQueryBuf->AppendL( KLeftBracket );
+		ConditionStatementL( EFalse, EAppendInFalse );
+		iQueryBuf->AppendL( KRightBracket );
+		}
+
+	if( condition.iSourceCondition != KNoOffset )
+		{
+		if( firstEventCondition == EFalse )
+			{
+			iQueryBuf->AppendL( KSpace );
+			iQueryBuf->AppendL( KAnd );
+			}
+		firstEventCondition = EFalse;
+
+		iSerializedBuffer->PositionL( condition.iSourceCondition );		
+		ConditionStatementL( EFalse, EAppendInFalse );
+		}
+
+	if( condition.iParticipantCondition != KNoOffset )
+		{
+		if( firstEventCondition == EFalse )
+			{
+			iQueryBuf->AppendL( KSpace );
+			iQueryBuf->AppendL( KAnd );
+			}
+		firstEventCondition = EFalse;
+
+		iSerializedBuffer->PositionL( condition.iParticipantCondition );		
+		ConditionStatementL( EFalse, EAppendInFalse );
+		}
+
+	// check event condition has URI comparsion
+	if( EEventConditionCompareNone != condition.iCompareMethod
+			&& KNoOffset != condition.iUriCondition )
+		{
+		if( firstEventCondition == EFalse )
+			{
+			iQueryBuf->AppendL( KSpace );
+			iQueryBuf->AppendL( KAnd );
+			}
+		firstEventCondition = EFalse;
+
+		switch( condition.iCompareMethod )
+			{
+			case EEventConditionCompareSourceURI:
+	        	// "Source="URI""
+	        	iQueryBuf->AppendL( KEventSourceEqual );
+	        	break;
+
+	        case EEventConditionCompareParticipantURI:
+	        	// "Participant="URI""
+		        iQueryBuf->AppendL( KEventParticipantEqual );
+				break;
+
+	        default:
+#ifdef _DEBUG
+	        	User::Panic( _L( "MdSFCAEC" ), KErrMdEUnknownConditionCompareMethod );
+#endif
+	        	User::Leave( KErrMdEUnknownConditionCompareMethod );
+			}
+
+		iSerializedBuffer->PositionL( condition.iUriCondition );
+		TPtrC16 eventUri = iSerializedBuffer->ReceivePtr16L();
+		iVariables.AppendL( TColumn( eventUri ) );		
+		}
+
+	iQueryBuf->AppendL( KRightBracket );
+	}
+
+// ---------------------------------------------------------------------------
+// AppendRelationConditionL                Help method for appending relation 
+//                                         condition for object query.
+// ---------------------------------------------------------------------------
+//
+void CMdSFindSqlClause::AppendRelationConditionL(TBool aNegated)
+	{
+	const TMdCRelationCondition& condition = 
+			TMdCRelationCondition::GetFromBufferL( *iSerializedBuffer );
+
+	if( ( ERelationConditionSideLeft == condition.iObjectSide ) || 
+		( ERelationConditionSideRight == condition.iObjectSide ) )
+		{
+		if( EQueryTypeRelation == iSearchCriteria->iQueryType )
+			{
+			// "SELECT RelationId FROM Relations"
+			iQueryBuf->AppendL( KSelectRelationIdFromRelation );
+			}
+		else
+			{
+			if( ERelationConditionSideLeft == condition.iObjectSide )
+				{
+				// "SELECT LeftObjectId FROM Relations"
+				iQueryBuf->AppendL( KSelectLeftObjectIdFromRelation );
+				}
+			else
+				{
+				// "SELECT RightObjectId FROM Relations"
+				iQueryBuf->AppendL( KSelectRightObjectIdFromRelation );
+				}
+			}
+
+		// ""namespace def ID" "
+		iQueryBuf->AppendL( iNamespaceIdDes );
+		iQueryBuf->AppendL( KSpace );
+		
+		// "WHERE(NOT Flags&?)"
+		iQueryBuf->AppendL( KWhereNotFlag );
+		iVariables.AppendL( TColumn( 
+				EMdERelationFlagNotPresent | 
+				EMdERelationFlagDeleted | 
+				EMdERelationFlagGarbageDeleted ) );
+
+		if( condition.iLeftObjectCondition != KNoOffset )
+			{
+			// "AND "
+			iQueryBuf->AppendL( KAnd );
+
+			// "NOT"
+			if( aNegated )
+			{
+				iQueryBuf->AppendL( KNot );
+			}
+
+			iQueryBuf->AppendL( KLeftBracket );
+
+			iQueryBuf->AppendL( KLeftBracket );
+			// append relation condition and left object condition
+			AppendRelationSideConditionL( ETrue, condition, 
+					ETrue, condition.iLeftObjectCondition );
+			iQueryBuf->AppendL( KRightBracket );
+
+			// append right object condition if it exists
+			if( condition.iRightObjectCondition != KNoOffset )
+				{
+				// "AND "
+				iQueryBuf->AppendL( KAnd );
+
+				iQueryBuf->AppendL( KLeftBracket );
+				// append only right object condition
+				AppendRelationSideConditionL( EFalse, condition, 
+						EFalse, condition.iRightObjectCondition );
+				iQueryBuf->AppendL( KRightBracket );
+				}
+
+			iQueryBuf->AppendL( KRightBracket );
+			}
+		else
+			{
+			// append right object condition if it exists
+			if( condition.iRightObjectCondition != KNoOffset )
+				{
+				// "AND "
+				iQueryBuf->AppendL( KAnd );
+				
+				// "NOT"
+				if( aNegated )
+				{
+					iQueryBuf->AppendL( KNot );
+				}
+
+				iQueryBuf->AppendL( KLeftBracket );
+				// append relation condition and right object condition
+				AppendRelationSideConditionL( ETrue, condition, 
+						EFalse, condition.iRightObjectCondition );
+				iQueryBuf->AppendL( KRightBracket );
+				}
+			}
+		}
+	else if( ERelationConditionSideEither == condition.iObjectSide )
+		{
+		// relation query
+		if( EQueryTypeRelation == iSearchCriteria->iQueryType )
+			{
+			// "SELECT RelationId FROM Relations"namespace def ID" "
+			iQueryBuf->AppendL( KSelectRelationIdFromRelation );
+			iQueryBuf->AppendL( iNamespaceIdDes );
+			iQueryBuf->AppendL( KSpace );
+		
+			// "WHERE(NOT Flags&?)"
+			iQueryBuf->AppendL( KWhereNotFlag );
+			iVariables.AppendL( TColumn( 
+					EMdERelationFlagNotPresent | 
+					EMdERelationFlagDeleted | 
+					EMdERelationFlagGarbageDeleted ) );
+			
+			// append left object condition if it exists
+			if( condition.iLeftObjectCondition != KNoOffset )
+				{
+				// "AND "
+				iQueryBuf->AppendL( KAnd );
+
+				// "NOT"
+				if( aNegated )
+					{
+					iQueryBuf->AppendL( KNot );
+					}
+
+				iQueryBuf->AppendL( KLeftBracket );
+
+				iQueryBuf->AppendL( KLeftBracket );
+				// append relation condition and left object condition
+				AppendRelationSideConditionL( ETrue, condition, 
+						ETrue, condition.iLeftObjectCondition );
+				iQueryBuf->AppendL( KRightBracket );
+
+				// append right object condition if it exists
+				if( condition.iRightObjectCondition != KNoOffset )
+					{
+					// "OR "
+					iQueryBuf->AppendL( KOr );
+
+					iQueryBuf->AppendL( KLeftBracket );
+					// append only right object condition
+					AppendRelationSideConditionL( EFalse, condition, 
+							EFalse, condition.iRightObjectCondition );
+					iQueryBuf->AppendL( KRightBracket );
+					}
+
+				iQueryBuf->AppendL( KRightBracket );
+				}
+			// append right object condition if it exists
+			else if( condition.iRightObjectCondition != KNoOffset )
+				{
+				// "AND "
+				iQueryBuf->AppendL( KAnd );
+
+				// "NOT"
+				if( aNegated )
+					{
+					iQueryBuf->AppendL( KNot );
+					}
+
+				iQueryBuf->AppendL( KLeftBracket );
+				// append relation condition and right object condition
+				AppendRelationSideConditionL( ETrue, condition, 
+						EFalse, condition.iRightObjectCondition );
+				iQueryBuf->AppendL( KRightBracket );
+				}
+			// append only relation conditions
+			else 
+				{
+				// "AND "
+				iQueryBuf->AppendL( KAnd );
+
+				// "NOT"
+				if( aNegated )
+					{
+					iQueryBuf->AppendL( KNot );
+					}
+
+				iQueryBuf->AppendL( KLeftBracket );
+				// append relation conditions
+				AppendRelationSideConditionL( ETrue, condition, 
+						EFalse, KNoOffset ); // no object condition
+				iQueryBuf->AppendL( KRightBracket );
+				}
+			}
+		// object or event query
+		else
+			{
+			if( condition.iLeftObjectCondition != KNoOffset )
+				{
+				// "SELECT LeftObjectId FROM Relations"namespace def ID" "
+				iQueryBuf->AppendL( KSelectLeftObjectIdFromRelation );
+				iQueryBuf->AppendL( iNamespaceIdDes );
+				iQueryBuf->AppendL( KSpace );
+
+				// "WHERE(NOT Flags&?)"
+				iQueryBuf->AppendL( KWhereNotFlag );
+				iVariables.AppendL( TColumn( 
+						EMdERelationFlagNotPresent | 
+						EMdERelationFlagDeleted | 
+						EMdERelationFlagGarbageDeleted ) );
+
+				// "AND "
+				iQueryBuf->AppendL( KAnd );
+				
+				// "NOT"
+				if( aNegated )
+					{
+					iQueryBuf->AppendL( KNot );
+					}
+
+				iQueryBuf->AppendL( KLeftBracket );
+				AppendRelationSideConditionL( ETrue, condition, 
+						ETrue, condition.iLeftObjectCondition );
+				iQueryBuf->AppendL( KRightBracket );
+
+				if( condition.iRightObjectCondition != KNoOffset )
+					{
+					// " UNION "
+					iQueryBuf->AppendL( KUnion );
+
+					// "SELECT RightObjectId FROM Relations"namespace def ID" "
+					iQueryBuf->AppendL( KSelectRightObjectIdFromRelation );
+					iQueryBuf->AppendL( iNamespaceIdDes );
+					iQueryBuf->AppendL( KSpace );
+					
+					// "WHERE(NOT Flags&?)"
+					iQueryBuf->AppendL( KWhereNotFlag );
+					iVariables.AppendL( TColumn( 
+							EMdERelationFlagNotPresent | 
+							EMdERelationFlagDeleted | 
+							EMdERelationFlagGarbageDeleted ) );
+
+					// "AND "
+					iQueryBuf->AppendL( KAnd );
+					
+					// "NOT"
+					if( aNegated )
+						{
+						iQueryBuf->AppendL( KNot );
+						}
+
+					iQueryBuf->AppendL( KLeftBracket );
+					AppendRelationSideConditionL( ETrue, condition, 
+							EFalse, condition.iRightObjectCondition );
+					iQueryBuf->AppendL( KRightBracket );
+					}
+				}
+			else
+				{
+				// "SELECT RightObjectId FROM Relations"namespace def ID" "
+				iQueryBuf->AppendL( KSelectRightObjectIdFromRelation );
+				iQueryBuf->AppendL( iNamespaceIdDes );
+				iQueryBuf->AppendL( KSpace );
+
+				// "WHERE(NOT Flags&?)"
+				iQueryBuf->AppendL( KWhereNotFlag );
+				iVariables.AppendL( TColumn( 
+						EMdERelationFlagNotPresent | 
+						EMdERelationFlagDeleted | 
+						EMdERelationFlagGarbageDeleted ) );
+
+				// "AND "
+				iQueryBuf->AppendL( KAnd );
+				
+				// "NOT"
+				if( aNegated )
+					{
+					iQueryBuf->AppendL( KNot );
+					}
+
+				iQueryBuf->AppendL( KLeftBracket );
+				AppendRelationSideConditionL( ETrue, condition, 
+						EFalse, condition.iRightObjectCondition );
+				iQueryBuf->AppendL( KRightBracket );
+				}
+			}
+		}
+	else
+		{
+		// unknown relation condition side
+#ifdef _DEBUG
+		User::Panic( _L("MdSFCARC") , KErrCorrupt );
+#endif
+		User::Leave( KErrCorrupt );
+		}
+	}
+
+void CMdSFindSqlClause::AppendRelationSideConditionL(
+		TBool aRelationConditions, 
+		const TMdCRelationCondition& aRelationCondition, 
+		TBool aLeftSide, TUint32 aRelationObjectConditionOffset)
+	{
+	TBool firstEventCondition = ETrue;
+
+	if( aRelationConditions )
+		{
+		if( aRelationCondition.iRelationId != KNoId )
+			{
+			firstEventCondition = EFalse;
+	
+			// "RelationId="relationID""
+			iQueryBuf->AppendL( KRelationIdEqual );
+			iVariables.AppendL( TColumn( aRelationCondition.iRelationId ) );
+			}
+	
+		if( aRelationCondition.iRelationIds.iPtr.iCount > 0 && 
+				aRelationCondition.iRelationIds.iPtr.iOffset != KNoOffset )
+			{
+			if( firstEventCondition == EFalse )
+				{
+				iQueryBuf->AppendL( KSpace );
+				iQueryBuf->AppendL( KAnd );
+				}
+			firstEventCondition = EFalse;
+	
+			// "RelationId IN("relationIDs")"
+			iQueryBuf->AppendL( KRelationIdIn );
+	
+			iQueryBuf->AppendL( KLeftBracket );
+	
+			iSerializedBuffer->PositionL( 
+					aRelationCondition.iRelationIds.iPtr.iOffset );
+	
+			TItemId relationId;
+			iSerializedBuffer->ReceiveL( relationId );
+			iQueryBuf->AppendL( KVariable );
+			iVariables.AppendL( TColumn( relationId ) );
+	
+			for( TInt32 i = 1; i < aRelationCondition.iRelationIds.iPtr.iCount; i++ )
+				{
+				iSerializedBuffer->ReceiveL( relationId );
+				iQueryBuf->AppendL( KCommaVariable );
+				iVariables.AppendL( TColumn( relationId ) );
+				}
+	
+			iQueryBuf->AppendL( KRightBracket );
+			}
+		
+		if( aRelationCondition.iRelationDefId != KNoDefId )
+			{
+			if( firstEventCondition == EFalse )
+				{
+				iQueryBuf->AppendL( KSpace );
+				iQueryBuf->AppendL( KAnd );
+				}
+			firstEventCondition = EFalse;
+	
+			// "RelationDefId="relationDefId""
+			iQueryBuf->AppendL( KRelationDefIdEqual );
+			iVariables.AppendL( TColumn( aRelationCondition.iRelationDefId ) );
+			}
+	
+		if( aRelationCondition.iGuid != KNoOffset )
+			{
+			if( firstEventCondition == EFalse )
+				{
+				iQueryBuf->AppendL( KSpace );
+				iQueryBuf->AppendL( KAnd );
+				}
+			firstEventCondition = EFalse;
+	
+			iSerializedBuffer->PositionL( aRelationCondition.iGuid );
+			
+			TInt64 guidHigh;
+			iSerializedBuffer->ReceiveL( guidHigh );
+			TInt64 guidLow;
+			iSerializedBuffer->ReceiveL( guidLow );
+			
+			// "RelationGuidHigh="relationGuidHigh" AND 
+			// RelationGuidLow="relationGuidLow""
+			iQueryBuf->AppendL( KRelationGuidEqual );
+			iVariables.AppendL( TColumn( guidHigh ) );
+			iVariables.AppendL( TColumn( guidLow ) );
+			}
+	
+		if( aRelationCondition.iParameterRange != KNoOffset )
+			{
+			if( firstEventCondition == EFalse )
+				{
+				iQueryBuf->AppendL( KSpace );
+				iQueryBuf->AppendL( KAnd );
+				}
+			firstEventCondition = EFalse;
+	
+			// "Parameter"
+			iQueryBuf->AppendL( KRelationParameter );
+			iSerializedBuffer->PositionL( aRelationCondition.iParameterRange );
+			AppendRangeL( EInt32RangeValue );
+			}
+	
+		if( aRelationCondition.iLastModifiedDateRange != KNoOffset )
+			{
+			if( firstEventCondition == EFalse )
+				{
+				iQueryBuf->AppendL( KSpace );
+				iQueryBuf->AppendL( KAnd );
+				}
+			firstEventCondition = EFalse;
+	
+			// "LastModifiedDate"
+			iQueryBuf->AppendL( KRelationLastModifiedDate );
+			iSerializedBuffer->PositionL( aRelationCondition.iLastModifiedDateRange );		
+			AppendRangeL( EInt64RangeValue );
+			}
+		}
+
+	// object condition on left or right side
+	if( aRelationObjectConditionOffset != KNoOffset )
+		{
+		if( firstEventCondition == EFalse )
+			{
+			iQueryBuf->AppendL( KSpace );
+			iQueryBuf->AppendL( KAnd );
+			}
+		firstEventCondition = EFalse;
+
+		iSerializedBuffer->PositionL( aRelationObjectConditionOffset );
+
+		if ( aLeftSide )
+			{
+			ConditionStatementL( EFalse, EAppendInRelationLeft );
+			}
+		else
+			{
+			ConditionStatementL( EFalse, EAppendInRelationRight );
+			}
+		}
+
+	// if there was no any condition add "empty" true condition
+	if( firstEventCondition )
+		{
+		iQueryBuf->AppendL( KEmptyTrue );
+		}
+	}
+
+// ---------------------------------------------------------------------------
+// AppendTableByObjectDefIdL               Help method for searching object 
+//                                         definition's table, based on 
+//                                         object definition's ID, and 
+//                                         appending those to buffer.
+// ---------------------------------------------------------------------------
+//
+void CMdSFindSqlClause::AppendTableByObjectDefIdL(TDefId aObjectDefId)
+	{
+	const CMdsObjectDef* objectDef = iNamespaceDef->GetObjectByIdL( aObjectDefId );
+
+	if ( !objectDef )
+		{
+#ifdef _DEBUG
+		User::Panic( _L("MdSFCAT1") , KErrMdEUnknownObjectDef );
+#endif
+		User::Leave( KErrMdEUnknownObjectDef );
+		}
+
+	iQueryBuf->AppendL( objectDef->GetName() );
+	iQueryBuf->AppendL( iNamespaceIdDes );
+	}
+
+// ---------------------------------------------------------------------------
+// AppendColumnByPropertyDefIdL            Help method for searching property 
+//                                         definition's column, based on 
+//                                         property definition's ID, and 
+//                                         appending those to buffer.
+// ---------------------------------------------------------------------------
+//
+void CMdSFindSqlClause::AppendColumnByPropertyDefIdL(TDefId aPropertyDefId, 
+		TDefId aObjectDefId, TBool aResult)
+	{
+	CMdsPropertyDef* propDef = NULL;
+
+	if( aObjectDefId == KNoDefId )
+		{
+		if ( !iObjectDef )
+			{
+			const CMdsObjectDef* baseObjectDef = iNamespaceDef->GetObjectByIdL(
+					KBaseObjectDefId );
+	
+			// base object definition must always exist
+			if ( !baseObjectDef )
+				{
+#ifdef _DEBUG
+				User::Panic( _L("MdSFCAC1") , KErrMdEUnknownObjectDef );
+#endif				
+				User::Leave( KErrMdEUnknownObjectDef );
+				}
+
+			propDef = CONST_CAST( CMdsPropertyDef*, 
+					baseObjectDef->GetPropertyByIdL( aPropertyDefId ) );
+
+			// if property definition doesn't exist in base object definition 
+			// search from whole namespace
+			if ( !propDef )
+				{
+				propDef = CONST_CAST( CMdsPropertyDef*, 
+						iNamespaceDef->GetPropertyL( aPropertyDefId ) );
+				}
+			}
+		else
+			{
+			propDef = CONST_CAST( CMdsPropertyDef*, 
+					iObjectDef->GetPropertyByIdL( aPropertyDefId ) );
+			}
+		}
+	else
+		{
+		const CMdsObjectDef* objDef = iNamespaceDef->GetObjectByIdL( 
+				aObjectDefId );
+		propDef = CONST_CAST( CMdsPropertyDef*, 
+				objDef->GetPropertyByIdL( aPropertyDefId ) );
+		}
+
+	if( propDef )
+		{
+		iQueryBuf->AppendL( propDef->GetName() );
+
+		if( aResult )
+			{
+			if( iAppendToResultRow )
+				{
+				// expected result for property's type
+			    iResultRow.AppendL( TColumn( propDef->GetSqlType() ) );
+
+			    iPropertyFilters.Append( propDef );
+				}
+			}
+		}
+	// object definition must always exist for given property definition ID
+	else
+		{
+#ifdef _DEBUG
+		User::Panic( _L("MdSFCAC2") , KErrMdEUnknownObjectDef );
+#endif
+		User::Leave( KErrMdEUnknownObjectDef );
+		}
+	}
+
+// ---------------------------------------------------------------------------
+// AppendGroupByL           Appends Group BY statements
+// ---------------------------------------------------------------------------
+//
+void CMdSFindSqlClause::AppendGroupByL()
+	{
+	// if query type is object query
+	if ( EQueryTypeObject == iSearchCriteria->iQueryType )
+		{
+		switch( iSearchCriteria->iQueryResultType )
+			{
+			case EQueryResultModeItem:
+			case EQueryResultModeId:
+			case EQueryResultModeCount:
+				{
+				// "GROUP BY BO.ObjectId "
+				iQueryBuf->AppendL( KGroupByObjectId );
+				}
+				break;
+
+			default:
+#ifdef _DEBUG
+				User::Panic( _L("MdSFCAGB") , KErrMdEUnknownQueryResultMode );
+#endif
+				User::Leave( KErrMdEUnknownQueryResultMode );
+			}
+		}
+	}
+
+// ---------------------------------------------------------------------------
+// AppendOrderByL           Appends ORDER BY statements
+// ---------------------------------------------------------------------------
+//
+void CMdSFindSqlClause::AppendOrderByL()
+    {
+	if( iSearchCriteria->iOrderRules.iPtr.iCount > 0 )
+		{
+		iQueryBuf->AppendL( KOrderBy );
+
+		iSerializedBuffer->PositionL( iSearchCriteria->iOrderRules.iPtr.iOffset );
+
+		// Add recursive all children.
+	    for( TUint32 i = 0; i < iSearchCriteria->iOrderRules.iPtr.iCount; i++)
+			{
+			if( i > 0 )
+				{
+				iQueryBuf->AppendL( KComma );
+				}
+
+			const TMdCOrderRule& orderRule = TMdCOrderRule::GetFromBufferL( 
+					*iSerializedBuffer );
+
+			switch( iSearchCriteria->iQueryType )
+				{
+				case EQueryTypeObject:
+					switch( orderRule.iOrderRule )
+						{
+						case EOrderRuleTypeProperty:
+							AppendColumnByPropertyDefIdL( orderRule.iPropertyDefId );
+							break;
+
+						case EOrderRuleTypeItemID:
+							iQueryBuf->AppendL( KBaseObjectObjectId );
+							break;
+
+						case EOrderRuleTypeObjectURI:
+							_LIT( KQueryBaseObjectURI, "BO.URI");
+							iQueryBuf->AppendL( KQueryBaseObjectURI );
+							break;
+
+						case EOrderRuleTypeObjectDef:
+							_LIT( KQueryBaseObjectDefId, "BO.ObjectDefId");
+							iQueryBuf->AppendL( KQueryBaseObjectDefId );
+							break;
+
+						case EOrderRuleTypeUsageCount:
+							_LIT( KQueryBaseObjectUsageCount, "BO.UsageCount");
+							iQueryBuf->AppendL( KQueryBaseObjectUsageCount );
+							break;
+
+						default:
+							User::Leave( KErrNotSupported );
+						}
+					break;
+
+				case EQueryTypeRelation:
+					switch( orderRule.iOrderRule )
+						{
+						case EOrderRuleTypeItemID:
+							iQueryBuf->AppendL( KRelationId );
+							break;
+
+						case EOrderRuleTypeLastModifiedDate:
+							iQueryBuf->AppendL( KRelationLastModifiedDate );
+							break;
+
+						case EOrderRuleTypeParameterValue:
+							iQueryBuf->AppendL( KRelationParameter );
+							break;
+
+						case EOrderRuleTypeLeftObjectID:
+							_LIT( KQueryRelationLeftObjectId, "LeftObjectId");
+							iQueryBuf->AppendL( KQueryRelationLeftObjectId );
+							break;
+
+						case EOrderRuleTypeRightObjectID:
+							_LIT( KQueryRelationRightObjectId, "RightObjectId");
+							iQueryBuf->AppendL( KQueryRelationRightObjectId );
+							break;
+
+						case EOrderRuleTypeRelationDef:
+							_LIT( KQueryRelationDef, "RelationDefId");
+							iQueryBuf->AppendL( KQueryRelationDef );
+							break;
+
+						default:
+							User::Leave( KErrNotSupported );
+						}
+					break;
+
+				case EQueryTypeEvent:
+					switch( orderRule.iOrderRule )
+						{
+						case EOrderRuleTypeItemID:
+							iQueryBuf->AppendL( KEventId );
+							break;
+
+						case EOrderRuleTypeCreationTime:
+							iQueryBuf->AppendL( KEventTimeStamp );
+							break;
+
+						case EOrderRuleTypeSourceURI:
+							_LIT( KQueryEventSource, "Source");
+							iQueryBuf->AppendL( KQueryEventSource );
+							break;
+
+						case EOrderRuleTypeParticipantURI:
+							_LIT( KQueryEventParticipant, "Participant");
+							iQueryBuf->AppendL( KQueryEventParticipant );
+							break;
+
+						case EOrderRuleTypeTargetObjectID:
+							_LIT( KQueryEventObjectId, "ObjectId");
+							iQueryBuf->AppendL( KQueryEventObjectId );
+							break;
+
+						case EOrderRuleTypeEventDef:
+							_LIT( KQueryEventDef, "EventDefId");
+							iQueryBuf->AppendL( KQueryEventDef );
+							break;
+
+						default:
+							User::Leave( KErrNotSupported );
+						}
+					break;
+
+				default:
+#ifdef _DEBUG
+					User::Panic( _L("MdSFCAOB") , KErrMdEUnknownQueryType );
+#endif
+					User::Leave( KErrMdEUnknownQueryType );
+				}
+
+			if ( !orderRule.iCaseSensitive )
+				{
+				iQueryBuf->AppendL( KNoCaseSensitive );
+				}
+
+			if( orderRule.iAscending )
+				{
+				iQueryBuf->AppendL( KAsc );
+				}
+			else
+				{
+				iQueryBuf->AppendL( KDesc );
+				}
+			}
+		
+		iQueryBuf->AppendL( KSpace );				
+		}
+    }
+
+// ---------------------------------------------------------------------------
+// AppendLimitAndOffsetL            LIMIT and OFFSET statements
+// ---------------------------------------------------------------------------
+//
+void CMdSFindSqlClause::AppendLimitAndOffsetL()
+    {
+    if ( iSearchCriteria->iOffset > 0 )
+    	{
+    	// 10 is maximum length of text format TUint32
+    	iQueryBuf->ReserveSpaceL( iQueryBuf->ConstBufferL().Length() + 
+    			2 * 10 );
+
+    	iQueryBuf->AppendL( KLimit );
+    	iQueryBuf->BufferL().AppendNum( iSearchCriteria->iLimit );
+    	iQueryBuf->AppendL( KComma );
+    	iQueryBuf->BufferL().AppendNum( iSearchCriteria->iOffset );
+    	}
+    else if ( iSearchCriteria->iLimit != KMaxTUint32 )
+    	{
+    	// 10 is maximum length of text format TUint32
+    	iQueryBuf->ReserveSpaceL( iQueryBuf->ConstBufferL().Length() + 
+    			10 );
+    	
+    	iQueryBuf->AppendL( KLimit );
+    	iQueryBuf->BufferL().AppendNum( iSearchCriteria->iLimit );
+    	}
+    }
+
+// ---------------------------------------------------------------------------
+// CopyVariablesL   Copies number of variables from variable table to the
+//                  end of the variable table
+// ---------------------------------------------------------------------------
+//
+void CMdSFindSqlClause::CopyVariablesL( TInt aStart, TInt aEnd )
+    {
+    TColumn column;
+    
+    for ( TInt i(aStart); i<aEnd; ++i )
+        {
+        column = iVariables.Column(i);
+        
+        switch( column.Type() )
+            {
+            case EColumnBool:
+                {
+                TBool v=0;
+                column.Get( v );
+                iVariables.AppendL( TColumn( v ) );
+                break;
+                }
+            case EColumnInt32:
+                {
+                TInt32 v=0;
+                column.Get( v );
+                iVariables.AppendL( TColumn( v ) );
+                break;
+                }
+            case EColumnUint32:
+                {
+                TUint32 v=0;
+                column.Get( v );
+                iVariables.AppendL( TColumn( v ) );
+                break;
+                }
+            case EColumnTime:
+                {
+                TTime v(0);
+                column.Get( v );
+                iVariables.AppendL( TColumn( v ) );
+                break;
+                }
+            case EColumnInt64:
+                {
+                TInt64 v=0;
+                column.Get( v );
+                iVariables.AppendL( TColumn( v ) );
+                break;
+                }
+            case EColumnReal32:
+                {
+                TReal32 v=0;
+                column.Get( v );
+                iVariables.AppendL( TColumn( v ) );
+                break;
+                }
+            case EColumnReal64:
+                {
+                TReal64 v=0;
+                column.Get( v );
+                iVariables.AppendL( TColumn( v ) );
+                break;
+                }
+            case EColumnDes16:
+                {
+                TPtrC16 v = TPtr16((TUint16*)0, 0); //KNullPtr16;
+                column.Get( v );
+                iVariables.AppendL( TColumn( v ) );
+                break;
+                }
+            default:
+#ifdef _DEBUG
+				User::Panic( _L("MdSFCCoV") , KErrMdEUnknownPropertyType );
+#endif            	
+                User::Leave( KErrMdEUnknownPropertyType );
+            }
+        }
+    }