<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"
		xmlns="http://www.ivoa.net/xml/ADQL/v1.0" xmlns:ad="http://www.ivoa.net/xml/ADQL/v1.0"
		xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
	
	<!-- 
		Stylesheet to convert ADQL/x v1.0 to an SQL string
		Version 1.0 (registry) - first release - July 8, 2005
		Aurelien STEBE -- ESAC - ESA
		Aurelien.Stebe@sciops.esa.int
	 -->
	
	<xsl:output method="text" indent="no"/>
	
	<!-- the root templates -->
	
	<xsl:template match="/ad:Select">
		<xsl:for-each select="ad:Where">
			<xsl:for-each select="ad:Condition">
				<xsl:apply-templates select="."/>
			</xsl:for-each>
		</xsl:for-each>
	</xsl:template>
	<xsl:template match="/ad:Where">
		<xsl:for-each select="ad:Condition">
			<xsl:apply-templates select="."/>
		</xsl:for-each>
	</xsl:template>
	
	<!-- the 'searchType' templates -->
	
	<xsl:template match="*[substring-after(@xsi:type, ':') = 'intersectionSearchType'] | *[@xsi:type = 'intersectionSearchType']">
		<xsl:apply-templates select="ad:Condition[1]"/>
		<xsl:text> AND </xsl:text>
		<xsl:apply-templates select="ad:Condition[2]"/>
	</xsl:template>
	<xsl:template match="*[substring-after(@xsi:type, ':') = 'unionSearchType'] | *[@xsi:type = 'unionSearchType']">
		<xsl:apply-templates select="ad:Condition[1]"/>
		<xsl:text> OR </xsl:text>
		<xsl:apply-templates select="ad:Condition[2]"/>
	</xsl:template>
	
	<xsl:template match="*[substring-after(@xsi:type, ':') = 'likePredType'] | *[@xsi:type = 'likePredType']">
		<xsl:apply-templates select="ad:Arg"/>
		<xsl:text> LIKE </xsl:text>
		<xsl:apply-templates select="ad:Pattern"/>
	</xsl:template>
	<xsl:template match="*[substring-after(@xsi:type, ':') = 'notLikePredType'] | *[@xsi:type = 'notLikePredType']">
		<xsl:apply-templates select="ad:Arg"/>
		<xsl:text> NOT LIKE </xsl:text>
		<xsl:apply-templates select="ad:Pattern"/>
	</xsl:template>
	
	<xsl:template match="*[substring-after(@xsi:type, ':') = 'inclusiveSearchType'] | *[@xsi:type = 'inclusiveSearchType']">
		<xsl:apply-templates select="ad:Expression"/>
		<xsl:text> IN (</xsl:text>
		<xsl:apply-templates select="ad:Set"/>
		<xsl:text>)</xsl:text>
	</xsl:template>
	<xsl:template match="*[substring-after(@xsi:type, ':') = 'exclusiveSearchType'] | *[@xsi:type = 'exclusiveSearchType']">
		<xsl:apply-templates select="ad:Expression"/>
		<xsl:text> NOT IN (</xsl:text>
		<xsl:apply-templates select="ad:Set"/>
		<xsl:text>)</xsl:text>
	</xsl:template>
	
	<xsl:template match="*[substring-after(@xsi:type, ':') = 'constantListSet'] | *[@xsi:type = 'constantListSet']">
		<xsl:variable name="set">
			<xsl:for-each select="ad:Item">
				<xsl:apply-templates select="."/>
				<xsl:text>, </xsl:text>
			</xsl:for-each>
		</xsl:variable>
		<xsl:value-of select="substring($set, 1, string-length($set)-2)"/>
	</xsl:template>
	<xsl:template match="*[substring-after(@xsi:type, ':') = 'ConstantListSet'] | *[@xsi:type = 'ConstantListSet']">
		<xsl:variable name="set">
			<xsl:for-each select="ad:Item">
				<xsl:apply-templates select="."/>
				<xsl:text>, </xsl:text>
			</xsl:for-each>
		</xsl:variable>
		<xsl:value-of select="substring($set, 1, string-length($set)-2)"/>
	</xsl:template>
	
	<xsl:template match="*[substring-after(@xsi:type, ':') = 'closedSearchType'] | *[@xsi:type = 'closedSearchType']">
		<xsl:text> (</xsl:text>
		<xsl:apply-templates select="ad:Condition"/>
		<xsl:text>) </xsl:text>
	</xsl:template>
	<xsl:template match="*[substring-after(@xsi:type, ':') = 'comparisonPredType'] | *[@xsi:type = 'comparisonPredType']">
		<xsl:apply-templates select="ad:Arg[1]"/>
		<xsl:value-of select="@Comparison"/>
		<xsl:apply-templates select="ad:Arg[2]"/>
	</xsl:template>
	
	<xsl:template match="*[substring-after(@xsi:type, ':') = 'betweenPredType'] | *[@xsi:type = 'betweenPredType']">
		<xsl:apply-templates select="ad:Arg[1]"/>
		<xsl:text> BETWEEN </xsl:text>
		<xsl:apply-templates select="ad:Arg[2]"/>
		<xsl:text> AND </xsl:text>
		<xsl:apply-templates select="ad:Arg[3]"/>
	</xsl:template>
	<xsl:template match="*[substring-after(@xsi:type, ':') = 'notBetweenPredType'] | *[@xsi:type = 'notBetweenPredType']">
		<xsl:apply-templates select="ad:Arg[1]"/>
		<xsl:text> NOT BETWEEN </xsl:text>
		<xsl:apply-templates select="ad:Arg[2]"/>
		<xsl:text> AND </xsl:text>
		<xsl:apply-templates select="ad:Arg[3]"/>
	</xsl:template>
	
	<xsl:template match="*[substring-after(@xsi:type, ':') = 'inverseSearchType'] | *[@xsi:type = 'inverseSearchType']">
		<xsl:text>NOT </xsl:text>
		<xsl:apply-templates select="ad:Condition"/>
	</xsl:template>
	
	<!-- the 'expressionType' templates -->
	
	<xsl:template match="*[substring-after(@xsi:type, ':') = 'closedExprType'] | *[@xsi:type = 'closedExprType']">
		<xsl:text> (</xsl:text>
		<xsl:apply-templates select="ad:Arg"/>
		<xsl:text>) </xsl:text>
	</xsl:template>
	
	<xsl:template match="*[substring-after(@xsi:type, ':') = 'binaryExprType'] | *[@xsi:type = 'binaryExprType']">
		<xsl:apply-templates select="ad:Arg[1]"/>
		<xsl:value-of select="@Oper"/>
		<xsl:apply-templates select="ad:Arg[2]"/>
	</xsl:template>
	<xsl:template match="*[substring-after(@xsi:type, ':') = 'unaryExprType'] | *[@xsi:type = 'unaryExprType']">
		<xsl:value-of select="@Oper"/>
		<xsl:apply-templates select="ad:Arg"/>
	</xsl:template>
	
	<xsl:template match="*[substring-after(@xsi:type, ':') = 'columnReferenceType'] | *[@xsi:type = 'columnReferenceType']">
		<xsl:choose>
			<xsl:when test="@xpathName">
				<xsl:value-of select="@xpathName"/>
			</xsl:when>
			<xsl:otherwise>
				<xsl:value-of select="@Name"/>
			</xsl:otherwise>
		</xsl:choose>
	</xsl:template>
	
	<xsl:template match="*[substring-after(@xsi:type, ':') = 'atomType'] | *[@xsi:type = 'atomType']">
		<xsl:apply-templates select="ad:Literal"/>
	</xsl:template>
	<xsl:template match="*[substring-after(@xsi:type, ':') = 'realType'] | *[@xsi:type = 'realType']">
		<xsl:value-of select="@Value"/>
	</xsl:template>
	<xsl:template match="*[substring-after(@xsi:type, ':') = 'integerType'] | *[@xsi:type = 'integerType']">
		<xsl:value-of select="@Value"/>
	</xsl:template>
	<xsl:template match="*[substring-after(@xsi:type, ':') = 'stringType'] | *[@xsi:type = 'stringType']">
		<xsl:text>'</xsl:text>
		<xsl:value-of select="@Value"/>
		<xsl:text>'</xsl:text>
	</xsl:template>
	
	<!-- the 'functionType' templates -->
	
	<xsl:template match="*[substring-after(@xsi:type, ':') = 'trigonometricFunctionType'] | *[@xsi:type = 'trigonometricFunctionType']">
		<xsl:value-of select="@Name"/>
		<xsl:text>(</xsl:text>
		<xsl:apply-templates select="ad:Arg"/>
		<xsl:text>)</xsl:text>
	</xsl:template>
	<xsl:template match="*[substring-after(@xsi:type, ':') = 'mathFunctionType'] | *[@xsi:type = 'mathFunctionType']">
		<xsl:value-of select="@Name"/>
		<xsl:text>(</xsl:text>
		<xsl:apply-templates select="ad:Arg"/>
		<xsl:text>)</xsl:text>
	</xsl:template>
	<xsl:template match="*[substring-after(@xsi:type, ':') = 'aggregateFunctionType'] | *[@xsi:type = 'aggregateFunctionType']">
		<xsl:value-of select="@Name"/>
		<xsl:text>(</xsl:text>
		<xsl:apply-templates select="ad:Arg"/>
		<xsl:text>)</xsl:text>
	</xsl:template>
	
	<xsl:template match="text()"/>
	
</xsl:stylesheet>

