Skip to content

Commit eb44008

Browse files
rayudu3745beikov
authored andcommitted
HHH-19991: Provide some fixes for spanner dialect
1 parent ab2c2d3 commit eb44008

File tree

3 files changed

+86
-3
lines changed

3 files changed

+86
-3
lines changed

hibernate-core/src/main/java/org/hibernate/dialect/SpannerDialect.java

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
import jakarta.persistence.Timeout;
99
import org.hibernate.LockMode;
1010
import org.hibernate.LockOptions;
11+
import org.hibernate.ScrollMode;
1112
import org.hibernate.StaleObjectStateException;
1213
import org.hibernate.boot.Metadata;
1314
import org.hibernate.boot.model.FunctionContributions;
@@ -25,6 +26,8 @@
2526
import org.hibernate.dialect.sql.ast.SpannerSqlAstTranslator;
2627
import org.hibernate.dialect.unique.UniqueDelegate;
2728
import org.hibernate.engine.jdbc.dialect.spi.DialectResolutionInfo;
29+
import org.hibernate.engine.jdbc.env.spi.IdentifierHelper;
30+
import org.hibernate.engine.jdbc.env.spi.IdentifierHelperBuilder;
2831
import org.hibernate.engine.jdbc.env.spi.SchemaNameResolver;
2932
import org.hibernate.engine.spi.SessionFactoryImplementor;
3033
import org.hibernate.engine.spi.SharedSessionContractImplementor;
@@ -50,6 +53,8 @@
5053
import org.hibernate.type.BasicTypeRegistry;
5154
import org.hibernate.type.StandardBasicTypes;
5255

56+
import java.sql.DatabaseMetaData;
57+
import java.sql.SQLException;
5358
import java.util.Date;
5459
import java.util.Map;
5560

@@ -502,6 +507,16 @@ public Exporter<Table> getTableExporter() {
502507
return this.spannerTableExporter;
503508
}
504509

510+
@Override
511+
public String getCreateTableString() {
512+
return "create table if not exists";
513+
}
514+
515+
@Override
516+
public boolean supportsIfExistsBeforeTableName() {
517+
return true;
518+
}
519+
505520
/* SELECT-related functions */
506521

507522
@Override
@@ -895,6 +910,32 @@ public boolean supportsRowValueConstructorSyntaxInInList() {
895910
return false;
896911
}
897912

913+
@Override
914+
public DmlTargetColumnQualifierSupport getDmlTargetColumnQualifierSupport() {
915+
return DmlTargetColumnQualifierSupport.TABLE_ALIAS;
916+
}
917+
918+
@Override
919+
public IdentifierHelper buildIdentifierHelper(
920+
IdentifierHelperBuilder builder,
921+
DatabaseMetaData metadata) throws SQLException {
922+
builder.applyReservedWords( metadata );
923+
builder.setAutoQuoteKeywords( true );
924+
builder.setAutoQuoteDollar( true );
925+
return super.buildIdentifierHelper( builder, metadata );
926+
}
927+
928+
@Override
929+
public ScrollMode defaultScrollMode() {
930+
return ScrollMode.FORWARD_ONLY;
931+
}
932+
933+
@Override
934+
public String getTruncateTableStatement(String tableName) {
935+
// spanner doesn't have truncate command, so we delete
936+
return "delete from " + tableName + " where true";
937+
}
938+
898939
/* Type conversion and casting */
899940

900941
/**

hibernate-core/src/main/java/org/hibernate/dialect/SpannerDialectTableExporter.java

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,14 @@
1313
import java.util.stream.StreamSupport;
1414

1515
import org.hibernate.boot.Metadata;
16+
import org.hibernate.boot.model.relational.InitCommand;
1617
import org.hibernate.boot.model.relational.SqlStringGenerationContext;
1718
import org.hibernate.mapping.Column;
1819
import org.hibernate.mapping.Index;
1920
import org.hibernate.mapping.Table;
2021
import org.hibernate.tool.schema.spi.Exporter;
2122

23+
import static java.util.Collections.addAll;
2224
import static org.hibernate.internal.util.collections.ArrayHelper.EMPTY_STRING_ARRAY;
2325

2426
/**
@@ -67,7 +69,7 @@ else if ( !table.getForeignKeyCollection().isEmpty() ) {
6769

6870
private String[] getTableString(Table table, Metadata metadata, Iterable<Column> keyColumns, SqlStringGenerationContext context) {
6971
String primaryKeyColNames = StreamSupport.stream( keyColumns.spliterator(), false )
70-
.map( Column::getName )
72+
.map( col -> col.getQuotedName( spannerDialect ) )
7173
.collect( Collectors.joining( "," ) );
7274

7375
StringJoiner colsAndTypes = new StringJoiner( "," );
@@ -76,7 +78,7 @@ private String[] getTableString(Table table, Metadata metadata, Iterable<Column>
7678
for ( Column column : table.getColumns() ) {
7779
final String sqlType = column.getSqlType( metadata );
7880
final String columnDeclaration =
79-
column.getName()
81+
column.getQuotedName(spannerDialect)
8082
+ " " + sqlType
8183
+ ( column.isNullable() ? this.spannerDialect.getNullColumnString( sqlType ) : " not null" );
8284
colsAndTypes.add( columnDeclaration );
@@ -92,6 +94,10 @@ private String[] getTableString(Table table, Metadata metadata, Iterable<Column>
9294
)
9395
);
9496

97+
for ( InitCommand initCommand : table.getInitCommands( context ) ) {
98+
addAll( statements, initCommand.initCommands() );
99+
}
100+
95101
return statements.toArray(EMPTY_STRING_ARRAY);
96102
}
97103

@@ -106,7 +112,7 @@ public String[] getSqlDropStrings(Table table, Metadata metadata, SqlStringGener
106112
ArrayList<String> dropStrings = new ArrayList<>();
107113

108114
for ( Index index : table.getIndexes().values() ) {
109-
dropStrings.add( "drop index " + index.getName() );
115+
dropStrings.add( "drop index if exists " + index.getName() );
110116
}
111117

112118
dropStrings.add( this.spannerDialect.getDropTableString( context.format( table.getQualifiedTableName() ) ) );

hibernate-core/src/main/java/org/hibernate/dialect/sql/ast/SpannerSqlAstTranslator.java

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,14 +13,17 @@
1313
import org.hibernate.sql.ast.spi.AbstractSqlAstTranslator;
1414
import org.hibernate.sql.ast.spi.SqlSelection;
1515
import org.hibernate.sql.ast.tree.Statement;
16+
import org.hibernate.sql.ast.tree.delete.DeleteStatement;
1617
import org.hibernate.sql.ast.tree.expression.Expression;
1718
import org.hibernate.sql.ast.tree.expression.Literal;
1819
import org.hibernate.sql.ast.tree.expression.SqlTuple;
1920
import org.hibernate.sql.ast.tree.expression.Summarization;
2021
import org.hibernate.sql.ast.tree.from.DerivedTableReference;
22+
import org.hibernate.sql.ast.tree.from.NamedTableReference;
2123
import org.hibernate.sql.ast.tree.select.QueryPart;
2224
import org.hibernate.sql.ast.tree.select.QuerySpec;
2325
import org.hibernate.sql.ast.tree.select.SelectClause;
26+
import org.hibernate.sql.ast.tree.update.UpdateStatement;
2427
import org.hibernate.sql.exec.spi.JdbcOperation;
2528

2629
/**
@@ -112,4 +115,37 @@ protected void renderDerivedTableReference(DerivedTableReference tableReference)
112115
}
113116
}
114117

118+
@Override
119+
protected void visitDeleteStatementOnly(DeleteStatement statement) {
120+
// Spanner requires a WHERE in delete clause so we add "where true" if there is none
121+
if ( !hasWhere( statement.getRestriction() ) ) {
122+
renderDeleteClause( statement );
123+
appendSql( " where true" );
124+
visitReturningColumns( statement.getReturningColumns() );
125+
} else {
126+
super.visitDeleteStatementOnly( statement );
127+
}
128+
}
129+
130+
@Override
131+
protected void visitUpdateStatementOnly(UpdateStatement statement) {
132+
// Spanner requires a WHERE in update clause so we add "where true" if there is none
133+
if ( !hasWhere( statement.getRestriction() ) ) {
134+
renderUpdateClause( statement );
135+
renderSetClause( statement.getAssignments() );
136+
appendSql( " where true" );
137+
visitReturningColumns( statement.getReturningColumns() );
138+
} else {
139+
super.visitUpdateStatementOnly( statement );
140+
}
141+
}
142+
143+
@Override
144+
protected void renderDmlTargetTableExpression(NamedTableReference tableReference) {
145+
super.renderDmlTargetTableExpression( tableReference );
146+
if ( getClauseStack().getCurrent() != Clause.INSERT ) {
147+
renderTableReferenceIdentificationVariable( tableReference );
148+
}
149+
}
150+
115151
}

0 commit comments

Comments
 (0)