FUNCTION ExtractClause LPARAMETERS tcClause, tcString * Pulls the clause named in tcClause out of a tcString and returns it LOCAL lcReturn, lnCount, lnIgnoreStart, lnIgnoreEnd, lcTemp lcReturn = '' lnCount = OCCURS(UPPER(tcClause),UPPER(tcString)) * Concatenate multiple instances of the clause in cases like UNIONS, where there can be multiple * WHERE or GROUP BY clauses. FOR i = 1 TO lnCount lnLoc = AT(UPPER(tcClause),UPPER(tcString)) IF lnLoc > 0 lnIgnoreStart = 0 lnIgnoreEnd = 0 lcTemp = ALLTRIM(SUBSTR(tcString,lnLoc+LEN(tcClause))) lcTemp = CHRTRAN(lcTemp,';',' ') * If there's a subselect, make sure we ignore it lnLoc = AT("(SELECT",UPPER(lcTemp)) IF lnLoc > 0 lnIgnoreStart = lnLoc lnIgnoreEnd = AT(")",SUBSTR(lcTemp,lnIgnoreStart))+lnIgnoreStart lnLoc = AT("(",SUBSTR(lcTemp,lnIgnoreStart)) IF lnLoc < lnIgnoreEnd * There are parens within the subselect and we've grabbed the wrong ending one lnIgnoreEnd = AT(")",SUBSTR(lcTemp,lnLoc+1))+lnLoc+1+lnIgnoreStart ENDIF ENDIF IF UPPER(tcClause) <> "WHERE" lnLoc = AT("WHERE",SUBSTR(UPPER(lcTemp),MAX(1,lnIgnoreEnd)))+lnIgnoreEnd IF lnLoc > 0 lcTemp = ALLTRIM(LEFT(lcTemp,lnLoc-1)) ENDIF ENDIF IF UPPER(tcClause) <> "ORDER BY" lnLoc = AT("ORDER BY",SUBSTR(UPPER(lcTemp),MAX(1,lnIgnoreEnd)))+lnIgnoreEnd IF lnLoc > 0 lcTemp = ALLTRIM(LEFT(lcTemp,lnLoc-1)) ENDIF ENDIF IF UPPER(tcClause) <> "GROUP BY" lnLoc = AT("GROUP BY",SUBSTR(UPPER(lcTemp),MAX(1,lnIgnoreEnd)))+lnIgnoreEnd IF lnLoc > 0 lcTemp = ALLTRIM(LEFT(lcTemp,lnLoc-1)) ENDIF ENDIF IF UPPER(tcClause) <> "HAVING" lnLoc = AT("HAVING",SUBSTR(UPPER(lcTemp),MAX(1,lnIgnoreEnd)))+lnIgnoreEnd IF lnLoc > 0 lcTemp = ALLTRIM(LEFT(lcTemp,lnLoc-1)) ENDIF ENDIF lnLoc = AT("UNION",SUBSTR(UPPER(lcTemp),MAX(1,lnIgnoreEnd)))+lnIgnoreEnd IF lnLoc > 0 lcTemp = ALLTRIM(LEFT(lcTemp,lnLoc-1)) ENDIF ENDIF IF NOT EMPTY(lcReturn) IF UPPER(tcClause) = "WHERE" lcReturn = lcReturn+" AND " ENDIF ENDIF lcReturn = lcReturn+lcTemp ENDFOR RETURN lcReturn ENDFUNC