Awhile ago we have created a set of xml schemas and xslt to represent different languages as xml, and to generate source from those xmls. This way we know to represent and generate: java, c#, cobol, and several sql dialects (read about languages xom on this site).
Here, we'd like to expose a nuisance we had with sql dialects schema.
Our goal was to define a basic sql schema, and dialect extensions. This way we assumed to express general and dialect specific constructs. So, lets consider an example.
General:
-- Select one row select * from A
DB2:
select * from A fetch first row only
T-SQL:
select top 1 * from A
Oracle:
select * from A where rownum = 1
All these queries have common core syntax, while at the same time have dialect specific means to express intention to return first row only.
Down to the xml schema basic select statement looks like this:
<xs:complexType name="select-statement"> <xs:complexContent> <xs:extension base="full-select-statement"> <xs:sequence> <xs:element name="columns" type="columns-clause"> <xs:element name="from" type="from-clause" minOccurs="0"> <xs:element name="where" type="unary-expression" minOccurs="0"/> <xs:element name="group-by" type="expression-list" minOccurs="0"/> <xs:element name="having" type="unary-expression" minOccurs="0"/> <xs:element name="order-by" type="order-by-clause" minOccurs="0"/> </xs:sequence> <xs:attribute name="specification" type="query-specification" use="optional" default="all"/> </xs:extension> </xs:complexContent> </xs:complexType>
Here all is relatively clear. The generic select looks like:
<sql:select> <sql:columns> <sql:column wildcard="true"/> </sql:columns> <sql:from> <sql:table name="A"/> </sql:from> </sql:select>
But how would you define dialect specifics?
E.g. for T-SQL we would like to see a markup:
<sql:select> <tsql:top> <sql:number value="1"/> </tsql:top> <sql:columns> <sql:column wildcard="true"/> </sql:columns> <sql:from> <sql:table name="A"/> </sql:from> </sql:select>
While for DB2 there should be:
<sql:select> <sql:columns> <sql:column wildcard="true"/> </sql:columns> <sql:from> <sql:table name="A"/> </sql:from> <db2:fetch-first rows="1"/> </sql:select>
So, again the quesions are:
Though we have tried several solutions to that problem, none is satisfactory enough. To allow extensions we have defined that all elements in sql schema are based on sql-element, which allows extensions:
sql-element
<xs:complexType name="sql-element" abstract="true"> <xs:sequence> <xs:element ref="extension" minOccurs="0" maxOccurs="unbounded"/> </xs:sequence> </xs:complexType> <xs:element name="extension" type="extension"/> <xs:complexType name="extension" abstract="true"> <xs:complexContent> <xs:extension base="sql-element"/> </xs:complexContent> </xs:complexType> ... <xs:element name="top" type="top-extension" substitutionGroup="sql:extension"/> <xs:complexType name="top-extension"> <xs:complexContent> <xs:extension base="sql:extension"> <xs:sequence> <xs:element ref="sql:expression"/> </xs:sequence> <xs:attribute name="percent" type="xs:boolean" use="optional" default="false"/> </xs:extension> </xs:complexContent> </xs:complexType>
Unfortunately, this creates too weak typed schema for extensions, thus intellisence suggests too many options.
Remember Me
a@href@title, b, blockquote@cite, em, i, strike, strong, sub, super, u