Skip to content

Commit 227bb21

Browse files
committed
HHH-19956: Add InterSystemsIRISSqlAstTranslator.java
1 parent 29c5b42 commit 227bb21

File tree

1 file changed

+202
-0
lines changed

1 file changed

+202
-0
lines changed
Lines changed: 202 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,202 @@
1+
/*
2+
* SPDX-License-Identifier: Apache-2.0
3+
* Copyright Red Hat Inc. and Hibernate Authors
4+
*/
5+
package org.hibernate.community.dialect;
6+
7+
import org.hibernate.dialect.DmlTargetColumnQualifierSupport;
8+
import org.hibernate.engine.spi.SessionFactoryImplementor;
9+
import org.hibernate.internal.util.collections.Stack;
10+
import org.hibernate.query.sqm.ComparisonOperator;
11+
import org.hibernate.sql.ast.Clause;
12+
import org.hibernate.sql.ast.spi.AbstractSqlAstTranslator;
13+
import org.hibernate.sql.ast.spi.SqlSelection;
14+
import org.hibernate.sql.ast.tree.MutationStatement;
15+
import org.hibernate.sql.ast.tree.Statement;
16+
import org.hibernate.sql.ast.tree.delete.DeleteStatement;
17+
import org.hibernate.sql.ast.tree.expression.BinaryArithmeticExpression;
18+
import org.hibernate.sql.ast.tree.expression.ColumnReference;
19+
import org.hibernate.sql.ast.tree.expression.Expression;
20+
import org.hibernate.sql.ast.tree.expression.SqlTuple;
21+
import org.hibernate.sql.ast.tree.from.DerivedTableReference;
22+
import org.hibernate.sql.ast.tree.from.QueryPartTableReference;
23+
import org.hibernate.sql.ast.tree.from.ValuesTableReference;
24+
import org.hibernate.sql.ast.tree.insert.InsertSelectStatement;
25+
import org.hibernate.sql.ast.tree.select.QueryGroup;
26+
import org.hibernate.sql.ast.tree.select.QueryPart;
27+
import org.hibernate.sql.ast.tree.select.QuerySpec;
28+
import org.hibernate.sql.ast.tree.update.UpdateStatement;
29+
import org.hibernate.sql.exec.spi.JdbcOperation;
30+
31+
import java.util.List;
32+
33+
public class InterSystemsIRISSqlAstTranslator<T extends JdbcOperation> extends AbstractSqlAstTranslator<T> {
34+
35+
protected InterSystemsIRISSqlAstTranslator(SessionFactoryImplementor sessionFactory, Statement statement) {
36+
super(sessionFactory, statement);
37+
}
38+
39+
40+
@Override
41+
protected void renderDeleteClause(DeleteStatement statement) {
42+
appendSql("delete");
43+
final Stack<Clause> clauseStack = getClauseStack();
44+
try {
45+
clauseStack.push(Clause.DELETE);
46+
appendSql(" from ");
47+
renderDmlTargetTableExpression(statement.getTargetTable());
48+
renderTableReferenceIdentificationVariable(statement.getTargetTable());
49+
}
50+
finally {
51+
clauseStack.pop();
52+
}
53+
}
54+
55+
56+
@Override
57+
protected void renderTupleComparisonStandard(
58+
List<SqlSelection> lhsSelections,
59+
SqlTuple rhsTuple,
60+
ComparisonOperator operator
61+
) {
62+
63+
if (operator == ComparisonOperator.EQUAL || operator == ComparisonOperator.NOT_EQUAL) {
64+
emulateTupleComparisonSelections(lhsSelections, rhsTuple, operator);
65+
}
66+
else {
67+
68+
super.renderTupleComparisonStandard(lhsSelections, rhsTuple, operator);
69+
}
70+
}
71+
72+
@SuppressWarnings("unchecked")
73+
protected void emulateTupleComparisonSelections(
74+
List<SqlSelection> lhsSelections,
75+
SqlTuple rhsTuple,
76+
ComparisonOperator operator
77+
) {
78+
final List<Expression> rhsExpressions = (List<Expression>) rhsTuple.getExpressions();
79+
80+
if (lhsSelections.size() != rhsExpressions.size()) {
81+
throw new IllegalArgumentException("Tuple size mismatch");
82+
}
83+
84+
final String joiner = (operator == ComparisonOperator.EQUAL) ? " and " : " or ";
85+
86+
appendSql(OPEN_PARENTHESIS);
87+
for (int i = 0; i < lhsSelections.size(); i++) {
88+
if (i > 0) appendSql(joiner);
89+
90+
lhsSelections.get(i).getExpression().accept(this);
91+
appendSql(operator.sqlText());
92+
rhsExpressions.get(i).accept(this);
93+
}
94+
appendSql(CLOSE_PARENTHESIS);
95+
}
96+
97+
@Override
98+
public void visitValuesTableReference(ValuesTableReference tableReference) {
99+
emulateValuesTableReferenceColumnAliasing(tableReference);
100+
}
101+
102+
@Override
103+
protected void renderUpdateClause(UpdateStatement updateStatement) {
104+
appendSql("update");
105+
final Stack<Clause> clauseStack = getClauseStack();
106+
try {
107+
clauseStack.push(Clause.UPDATE);
108+
append(WHITESPACE);
109+
renderDmlTargetTableExpression(updateStatement.getTargetTable());
110+
renderTableReferenceIdentificationVariable(updateStatement.getTargetTable());
111+
}
112+
finally {
113+
clauseStack.pop();
114+
}
115+
}
116+
117+
118+
@Override
119+
protected String determineColumnReferenceQualifier(ColumnReference columnReference) {
120+
final DmlTargetColumnQualifierSupport qualifierSupport = getDialect().getDmlTargetColumnQualifierSupport();
121+
final MutationStatement currentDmlStatement;
122+
final String dmlAlias;
123+
124+
if ( getClauseStack().getCurrent() != Clause.SET
125+
|| !( ( currentDmlStatement = getCurrentDmlStatement() ) instanceof InsertSelectStatement)
126+
|| ( dmlAlias = currentDmlStatement.getTargetTable().getIdentificationVariable() ) == null
127+
|| !dmlAlias.equals( columnReference.getQualifier() ) ) {
128+
return columnReference.getQualifier();
129+
}
130+
// Qualify the column reference with the table expression also when in subqueries
131+
else if ( qualifierSupport != DmlTargetColumnQualifierSupport.NONE || !getQueryPartStack().isEmpty() ) {
132+
return getCurrentDmlStatement().getTargetTable().getTableExpression();
133+
}
134+
else {
135+
return null;
136+
}
137+
}
138+
139+
@Override
140+
public void visitBinaryArithmeticExpression(BinaryArithmeticExpression arithmeticExpression) {
141+
if ( isIntegerDivisionEmulationRequired( arithmeticExpression ) ) {
142+
visitArithmeticOperand( arithmeticExpression.getLeftHandOperand() );
143+
appendSql(" \\ ");
144+
visitArithmeticOperand( arithmeticExpression.getRightHandOperand() );
145+
}
146+
else {
147+
super.visitBinaryArithmeticExpression(arithmeticExpression);
148+
}
149+
}
150+
151+
@Override
152+
public void visitQueryGroup(QueryGroup queryGroup) {
153+
if ( shouldEmulateFetchClause( queryGroup ) ) {
154+
emulateFetchOffsetWithWindowFunctions( queryGroup, true );
155+
}
156+
else {
157+
super.visitQueryGroup( queryGroup );
158+
}
159+
}
160+
161+
@Override
162+
public void visitQuerySpec(QuerySpec querySpec) {
163+
if ( shouldEmulateFetchClause( querySpec ) ) {
164+
emulateFetchOffsetWithWindowFunctions( querySpec, true );
165+
}
166+
else {
167+
super.visitQuerySpec( querySpec );
168+
}
169+
}
170+
171+
protected boolean shouldEmulateFetchClause(QueryPart queryPart) {
172+
// Check if current query part is already row numbering to avoid infinite recursion
173+
if ( getQueryPartForRowNumbering() == queryPart || isRowsOnlyFetchClauseType( queryPart ) ) {
174+
return false;
175+
}
176+
return !getDialect().supportsFetchClause( queryPart.getFetchClauseType() );
177+
}
178+
179+
180+
@Override
181+
protected void renderDerivedTableReferenceIdentificationVariable(DerivedTableReference tableReference) {
182+
renderTableReferenceIdentificationVariable( tableReference );
183+
}
184+
185+
@Override
186+
public void visitQueryPartTableReference(QueryPartTableReference tableReference) {
187+
emulateQueryPartTableReferenceColumnAliasing( tableReference );
188+
}
189+
190+
@Override
191+
protected void renderFromClauseAfterUpdateSet(UpdateStatement statement) {
192+
if ( statement.getFromClause().getRoots().isEmpty() ) {
193+
appendSql( " from " );
194+
renderDmlTargetTableExpression( statement.getTargetTable() );
195+
renderTableReferenceIdentificationVariable(statement.getTargetTable());
196+
}
197+
else {
198+
visitFromClause( statement.getFromClause() );
199+
}
200+
}
201+
202+
}

0 commit comments

Comments
 (0)