sortKey = getColNameFromJSExpr( cx, src.getExpression() );
ColumnInfo columnInfo = getColInfoFromJSExpr( cx, src.getExpression( ) ); sortIndex = columnInfo.getColumnIndex(); sortKey = columnInfo.getColumnName( );
		protected void populateOdiQuery( ) throws DataException		{			assert odiQuery != null;			assert scope != null;			assert queryDefn != null;						Context cx = Context.enter();			try			{				// Set grouping				List groups = queryDefn.getGroups();				if ( groups != null && ! groups.isEmpty() )				{					IQuery.GroupSpec[] groupSpecs = new IQuery.GroupSpec[ groups.size() ];					Iterator it = groups.iterator();					for ( int i = 0; it.hasNext(); i++ )					{						IGroupDefinition src = (IGroupDefinition) it.next();						IQuery.GroupSpec dest = groupDefnToSpec(cx, src);						groupSpecs[i] = dest;					}					odiQuery.setGrouping( Arrays.asList( groupSpecs));				}								// Set sorting				List sorts = queryDefn.getSorts();				if ( sorts != null && !sorts.isEmpty( ) )				{					IQuery.SortSpec[] sortSpecs = new IQuery.SortSpec[ sorts.size() ];					Iterator it = sorts.iterator();					for ( int i = 0; it.hasNext(); i++ )					{						ISortDefinition src = (ISortDefinition) it.next();						String sortKey = src.getColumn();						if ( sortKey == null || sortKey.length() == 0 )						{							// Group key expressed as expression; convert it to column name							// TODO support key expression in the future by creating implicit							// computed columns							sortKey = getColNameFromJSExpr( cx, src.getExpression() );						}						IQuery.SortSpec dest = 	new IQuery.SortSpec( sortKey, 									src.getSortDirection() == ISortDefinition.SORT_ASC );						sortSpecs[i] = dest;					}					odiQuery.setOrdering( Arrays.asList( sortSpecs));				}			    // set computed column event			    if ( dataSet != null )				{					List computedColumns = this.dataSet.getComputedColumns( );					if ( computedColumns != null && computedColumns.size( ) > 0 )					{						IResultObjectEvent objectEvent = new ComputedColumnHelper( this.scope,								this.rowObject,								computedColumns );						odiQuery.addOnFetchEvent( objectEvent );					}				}			    			    // set Onfetch event - this should be added after computed column and before filtering			    if ( dataSet != null )			    {			    	String onFetchScript = dataSet.getOnFetchScript();			    	if ( onFetchScript != null && onFetchScript.length() > 0 )			    	{			    		OnFetchScriptHelper event = new OnFetchScriptHelper( dataSet ); 			    		odiQuery.addOnFetchEvent( event );			    	}			    }			    				// Set filtering		    	assert rowObject != null;		    	assert scope != null;			    // set filter event			    List mergedFilters = new ArrayList( );			    if ( queryDefn.getFilters( ) != null )				{					mergedFilters.addAll( queryDefn.getFilters( ) );				}			    			    if ( dataSet != null &&		    		 dataSet.getFilters( ) != null )				{					mergedFilters.addAll( dataSet.getFilters( ) );				}			    			    if ( mergedFilters.size() > 0 )			    {			    	IResultObjectEvent objectEvent = new FilterByRow( mergedFilters, 							scope,  rowObject );			    	odiQuery.addOnFetchEvent( objectEvent );			    }			    				// specify max rows the query should fetch			    odiQuery.setMaxRows( queryDefn.getMaxRows() );			}			finally			{				Context.exit();			}		}