You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@polygene.apache.org by ni...@apache.org on 2017/04/15 08:25:54 UTC
[03/19] polygene-java git commit: Bring in Stanislav's sql-generator
from GutHub, after his consent in
https://lists.apache.org/thread.html/797352ce2ad7aa7b755720a98f545a176e6050e35f56db113ba115fb@%3Cdev.polygene.apache.org%3E
http://git-wip-us.apache.org/repos/asf/polygene-java/blob/a36086b6/libraries/sql-generator/src/main/java/org/apache/polygene/library/sql/generator/implementation/transformation/ModificationProcessing.java
----------------------------------------------------------------------
diff --git a/libraries/sql-generator/src/main/java/org/apache/polygene/library/sql/generator/implementation/transformation/ModificationProcessing.java b/libraries/sql-generator/src/main/java/org/apache/polygene/library/sql/generator/implementation/transformation/ModificationProcessing.java
new file mode 100644
index 0000000..835ada1
--- /dev/null
+++ b/libraries/sql-generator/src/main/java/org/apache/polygene/library/sql/generator/implementation/transformation/ModificationProcessing.java
@@ -0,0 +1,291 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *
+ */
+package org.apache.polygene.library.sql.generator.implementation.transformation;
+
+import java.util.Iterator;
+import org.apache.polygene.library.sql.generator.grammar.common.SQLConstants;
+import org.apache.polygene.library.sql.generator.grammar.common.ValueExpression;
+import org.apache.polygene.library.sql.generator.grammar.modification.ColumnSourceByQuery;
+import org.apache.polygene.library.sql.generator.grammar.modification.ColumnSourceByValues;
+import org.apache.polygene.library.sql.generator.grammar.modification.DeleteBySearch;
+import org.apache.polygene.library.sql.generator.grammar.modification.DynamicColumnSource;
+import org.apache.polygene.library.sql.generator.grammar.modification.InsertStatement;
+import org.apache.polygene.library.sql.generator.grammar.modification.SetClause;
+import org.apache.polygene.library.sql.generator.grammar.modification.TargetTable;
+import org.apache.polygene.library.sql.generator.grammar.modification.UpdateBySearch;
+import org.apache.polygene.library.sql.generator.grammar.modification.UpdateSourceByExpression;
+import org.apache.polygene.library.sql.generator.grammar.query.QueryExpression;
+import org.apache.polygene.library.sql.generator.implementation.transformation.spi.SQLProcessorAggregator;
+
+/**
+ * @author Stanislav Muhametsin
+ */
+public class ModificationProcessing
+{
+
+ public static abstract class DynamicColumnSourceProcessor<SourceType extends DynamicColumnSource>
+ extends
+ AbstractProcessor<SourceType>
+ {
+ public DynamicColumnSourceProcessor( Class<? extends SourceType> realType )
+ {
+ super( realType );
+ }
+
+ @Override
+ protected void doProcess( SQLProcessorAggregator processor, SourceType object,
+ StringBuilder builder )
+ {
+ if( object.getColumnNames() != null )
+ {
+ processor.process( object.getColumnNames(), builder );
+ }
+ this.doProcessColumnSource( processor, object, builder );
+ }
+
+ protected abstract void doProcessColumnSource( SQLProcessorAggregator processor,
+ SourceType object,
+ StringBuilder builder );
+ }
+
+ public static class ColumnSourceByQueryProcessor extends
+ DynamicColumnSourceProcessor<ColumnSourceByQuery>
+ {
+
+ public ColumnSourceByQueryProcessor()
+ {
+ this( ColumnSourceByQuery.class );
+ }
+
+ protected ColumnSourceByQueryProcessor( Class<? extends ColumnSourceByQuery> realType )
+ {
+ super( realType );
+ }
+
+ @Override
+ protected void doProcessColumnSource( SQLProcessorAggregator processor,
+ ColumnSourceByQuery object,
+ StringBuilder builder )
+ {
+ builder.append( SQLConstants.NEWLINE );
+ processor.process( object.getQuery(), builder );
+ }
+ }
+
+ public static class ColumnSourceByValuesProcessor extends
+ DynamicColumnSourceProcessor<ColumnSourceByValues>
+ {
+
+ public ColumnSourceByValuesProcessor()
+ {
+ this( ColumnSourceByValues.class );
+ }
+
+ public ColumnSourceByValuesProcessor( Class<? extends ColumnSourceByValues> realType )
+ {
+ super( realType );
+ }
+
+ @Override
+ protected void doProcessColumnSource( SQLProcessorAggregator processor,
+ ColumnSourceByValues object,
+ StringBuilder builder )
+ {
+ builder.append( SQLConstants.NEWLINE ).append( "VALUES" )
+ .append( SQLConstants.OPEN_PARENTHESIS );
+ Iterator<ValueExpression> iter = object.getValues().iterator();
+ while( iter.hasNext() )
+ {
+ ValueExpression next = iter.next();
+ boolean needParenthesis = next instanceof QueryExpression;
+ if( needParenthesis )
+ {
+ builder.append( SQLConstants.OPEN_PARENTHESIS );
+ }
+ processor.process( next, builder );
+ if( needParenthesis )
+ {
+ builder.append( SQLConstants.CLOSE_PARENTHESIS );
+ }
+ if( iter.hasNext() )
+ {
+ builder.append( SQLConstants.COMMA ).append( SQLConstants.TOKEN_SEPARATOR );
+ }
+ }
+ builder.append( SQLConstants.CLOSE_PARENTHESIS );
+ }
+ }
+
+ public static class DeleteBySearchProcessor extends AbstractProcessor<DeleteBySearch>
+ {
+ public DeleteBySearchProcessor()
+ {
+ this( DeleteBySearch.class );
+ }
+
+ public DeleteBySearchProcessor( Class<? extends DeleteBySearch> realType )
+ {
+ super( realType );
+ }
+
+ @Override
+ protected void doProcess( SQLProcessorAggregator processor, DeleteBySearch object,
+ StringBuilder builder )
+ {
+ builder.append( "DELETE FROM" ).append( SQLConstants.TOKEN_SEPARATOR );
+ processor.process( object.getTargetTable(), builder );
+ QueryProcessing.processOptionalBooleanExpression( processor, builder,
+ object.getWhere(),
+ SQLConstants.NEWLINE, SQLConstants.WHERE );
+ }
+ }
+
+ public static class InsertStatementProcessor extends AbstractProcessor<InsertStatement>
+ {
+ public InsertStatementProcessor()
+ {
+ this( InsertStatement.class );
+ }
+
+ public InsertStatementProcessor( Class<? extends InsertStatement> realType )
+ {
+ super( realType );
+ }
+
+ @Override
+ protected void doProcess( SQLProcessorAggregator processor, InsertStatement object,
+ StringBuilder builder )
+ {
+ builder.append( "INSERT INTO" ).append( SQLConstants.TOKEN_SEPARATOR );
+ processor.process( object.getTableName(), builder );
+ builder.append( SQLConstants.TOKEN_SEPARATOR );
+ processor.process( object.getColumnSource(), builder );
+ }
+ }
+
+ public static class SetClauseProcessor extends AbstractProcessor<SetClause>
+ {
+ public SetClauseProcessor()
+ {
+ this( SetClause.class );
+ }
+
+ public SetClauseProcessor( Class<? extends SetClause> realType )
+ {
+ super( realType );
+ }
+
+ @Override
+ protected void doProcess( SQLProcessorAggregator processor, SetClause object,
+ StringBuilder builder )
+ {
+ builder.append( object.getUpdateTarget() ).append( SQLConstants.TOKEN_SEPARATOR )
+ .append( "=" )
+ .append( SQLConstants.TOKEN_SEPARATOR );
+ processor.process( object.getUpdateSource(), builder );
+ }
+ }
+
+ public static class TargetTableProcessor extends AbstractProcessor<TargetTable>
+ {
+ public TargetTableProcessor()
+ {
+ this( TargetTable.class );
+ }
+
+ protected TargetTableProcessor( Class<? extends TargetTable> realType )
+ {
+ super( realType );
+ }
+
+ @Override
+ protected void doProcess( SQLProcessorAggregator processor, TargetTable object,
+ StringBuilder builder )
+ {
+ Boolean isOnly = object.isOnly();
+ if( isOnly )
+ {
+ builder.append( "ONLY" ).append( SQLConstants.OPEN_PARENTHESIS );
+ }
+ processor.process( object.getTableName(), builder );
+ if( isOnly )
+ {
+ builder.append( SQLConstants.CLOSE_PARENTHESIS );
+ }
+ }
+ }
+
+ public static class UpdateBySearchProcessor extends AbstractProcessor<UpdateBySearch>
+ {
+ public UpdateBySearchProcessor()
+ {
+ this( UpdateBySearch.class );
+ }
+
+ protected UpdateBySearchProcessor( Class<? extends UpdateBySearch> realType )
+ {
+ super( realType );
+ }
+
+ @Override
+ protected void doProcess( SQLProcessorAggregator processor, UpdateBySearch object,
+ StringBuilder builder )
+ {
+ builder.append( "UPDATE" ).append( SQLConstants.TOKEN_SEPARATOR );
+ processor.process( object.getTargetTable(), builder );
+ builder.append( SQLConstants.NEWLINE ).append( "SET" )
+ .append( SQLConstants.TOKEN_SEPARATOR );
+ Iterator<SetClause> iter = object.getSetClauses().iterator();
+ while( iter.hasNext() )
+ {
+ processor.process( iter.next(), builder );
+ if( iter.hasNext() )
+ {
+ builder.append( SQLConstants.COMMA ).append( SQLConstants.TOKEN_SEPARATOR );
+ }
+ }
+ QueryProcessing.processOptionalBooleanExpression( processor, builder,
+ object.getWhere(),
+ SQLConstants.NEWLINE, SQLConstants.WHERE );
+ }
+ }
+
+ public static class UpdateSourceByExpressionProcessor extends
+ AbstractProcessor<UpdateSourceByExpression>
+ {
+ public UpdateSourceByExpressionProcessor()
+ {
+ this( UpdateSourceByExpression.class );
+ }
+
+ public UpdateSourceByExpressionProcessor( Class<? extends UpdateSourceByExpression> realType )
+ {
+ super( realType );
+ }
+
+ @Override
+ protected void doProcess( SQLProcessorAggregator processor,
+ UpdateSourceByExpression object,
+ StringBuilder builder )
+ {
+ processor.process( object.getValueExpression(), builder );
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/polygene-java/blob/a36086b6/libraries/sql-generator/src/main/java/org/apache/polygene/library/sql/generator/implementation/transformation/NoOpProcessor.java
----------------------------------------------------------------------
diff --git a/libraries/sql-generator/src/main/java/org/apache/polygene/library/sql/generator/implementation/transformation/NoOpProcessor.java b/libraries/sql-generator/src/main/java/org/apache/polygene/library/sql/generator/implementation/transformation/NoOpProcessor.java
new file mode 100644
index 0000000..e6bc330
--- /dev/null
+++ b/libraries/sql-generator/src/main/java/org/apache/polygene/library/sql/generator/implementation/transformation/NoOpProcessor.java
@@ -0,0 +1,34 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *
+ */
+package org.apache.polygene.library.sql.generator.implementation.transformation;
+
+import org.apache.polygene.library.sql.generator.Typeable;
+import org.apache.polygene.library.sql.generator.implementation.transformation.spi.SQLProcessor;
+import org.apache.polygene.library.sql.generator.implementation.transformation.spi.SQLProcessorAggregator;
+
+public class NoOpProcessor
+ implements SQLProcessor
+{
+
+ public void process( SQLProcessorAggregator processor, Typeable<?> object, StringBuilder builder )
+ {
+ // No-op
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/polygene-java/blob/a36086b6/libraries/sql-generator/src/main/java/org/apache/polygene/library/sql/generator/implementation/transformation/ProcessorUtils.java
----------------------------------------------------------------------
diff --git a/libraries/sql-generator/src/main/java/org/apache/polygene/library/sql/generator/implementation/transformation/ProcessorUtils.java b/libraries/sql-generator/src/main/java/org/apache/polygene/library/sql/generator/implementation/transformation/ProcessorUtils.java
new file mode 100644
index 0000000..15bb6b3
--- /dev/null
+++ b/libraries/sql-generator/src/main/java/org/apache/polygene/library/sql/generator/implementation/transformation/ProcessorUtils.java
@@ -0,0 +1,60 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *
+ */
+package org.apache.polygene.library.sql.generator.implementation.transformation;
+
+import org.apache.polygene.library.sql.generator.grammar.common.SQLConstants;
+import org.apache.polygene.library.sql.generator.grammar.common.SetQuantifier;
+import org.apache.polygene.library.sql.generator.grammar.manipulation.DropBehaviour;
+
+/**
+ * @author Stanislav Muhametsin
+ */
+public class ProcessorUtils
+{
+ public static Boolean notNullAndNotEmpty( String str )
+ {
+ return str != null && str.trim().length() > 0;
+ }
+
+ public static void processSetQuantifier( SetQuantifier quantifier, StringBuilder builder )
+ {
+ if( quantifier == SetQuantifier.ALL )
+ {
+ builder.append( "ALL" );
+ }
+ else
+ {
+ builder.append( "DISTINCT" );
+ }
+ }
+
+ public static void processDropBehaviour( DropBehaviour behaviour, StringBuilder builder )
+ {
+ builder.append( SQLConstants.TOKEN_SEPARATOR );
+ if( behaviour == DropBehaviour.CASCADE )
+ {
+ builder.append( "CASCADE" );
+ }
+ else
+ {
+ builder.append( "RESTRICT" );
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/polygene-java/blob/a36086b6/libraries/sql-generator/src/main/java/org/apache/polygene/library/sql/generator/implementation/transformation/QueryProcessing.java
----------------------------------------------------------------------
diff --git a/libraries/sql-generator/src/main/java/org/apache/polygene/library/sql/generator/implementation/transformation/QueryProcessing.java b/libraries/sql-generator/src/main/java/org/apache/polygene/library/sql/generator/implementation/transformation/QueryProcessing.java
new file mode 100644
index 0000000..e49bf15
--- /dev/null
+++ b/libraries/sql-generator/src/main/java/org/apache/polygene/library/sql/generator/implementation/transformation/QueryProcessing.java
@@ -0,0 +1,615 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *
+ */
+package org.apache.polygene.library.sql.generator.implementation.transformation;
+
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Objects;
+import org.apache.polygene.library.sql.generator.Typeable;
+import org.apache.polygene.library.sql.generator.grammar.booleans.BooleanExpression;
+import org.apache.polygene.library.sql.generator.grammar.common.NonBooleanExpression;
+import org.apache.polygene.library.sql.generator.grammar.common.SQLConstants;
+import org.apache.polygene.library.sql.generator.grammar.common.ValueExpression;
+import org.apache.polygene.library.sql.generator.grammar.literals.LiteralExpression;
+import org.apache.polygene.library.sql.generator.grammar.query.ColumnReferences;
+import org.apache.polygene.library.sql.generator.grammar.query.ColumnReferences.ColumnReferenceInfo;
+import org.apache.polygene.library.sql.generator.grammar.query.CorrespondingSpec;
+import org.apache.polygene.library.sql.generator.grammar.query.FromClause;
+import org.apache.polygene.library.sql.generator.grammar.query.GroupByClause;
+import org.apache.polygene.library.sql.generator.grammar.query.GroupingElement;
+import org.apache.polygene.library.sql.generator.grammar.query.LimitSpecification;
+import org.apache.polygene.library.sql.generator.grammar.query.OffsetSpecification;
+import org.apache.polygene.library.sql.generator.grammar.query.OrderByClause;
+import org.apache.polygene.library.sql.generator.grammar.query.Ordering;
+import org.apache.polygene.library.sql.generator.grammar.query.OrdinaryGroupingSet;
+import org.apache.polygene.library.sql.generator.grammar.query.QueryExpression;
+import org.apache.polygene.library.sql.generator.grammar.query.QueryExpressionBody;
+import org.apache.polygene.library.sql.generator.grammar.query.QueryExpressionBodyBinary;
+import org.apache.polygene.library.sql.generator.grammar.query.QuerySpecification;
+import org.apache.polygene.library.sql.generator.grammar.query.RowDefinition;
+import org.apache.polygene.library.sql.generator.grammar.query.RowSubQuery;
+import org.apache.polygene.library.sql.generator.grammar.query.RowValueConstructor;
+import org.apache.polygene.library.sql.generator.grammar.query.SelectColumnClause;
+import org.apache.polygene.library.sql.generator.grammar.query.SetOperation;
+import org.apache.polygene.library.sql.generator.grammar.query.SortSpecification;
+import org.apache.polygene.library.sql.generator.grammar.query.TableReference;
+import org.apache.polygene.library.sql.generator.grammar.query.TableValueConstructor;
+import org.apache.polygene.library.sql.generator.implementation.grammar.booleans.BooleanUtils;
+import org.apache.polygene.library.sql.generator.implementation.transformation.spi.SQLProcessorAggregator;
+import org.slf4j.LoggerFactory;
+
+/**
+ * @author Stanislav Muhametsin
+ */
+public class QueryProcessing
+{
+
+ public static void processOptionalBooleanExpression( SQLProcessorAggregator processor,
+ StringBuilder builder,
+ BooleanExpression expression, String prefix, String name )
+ {
+ if( expression != null && !BooleanUtils.isEmpty( expression ) )
+ {
+ processOptional( processor, builder, expression, prefix, name );
+ }
+ }
+
+ public static void processOptional( SQLProcessorAggregator processor, StringBuilder builder,
+ Typeable<?> element,
+ String prefix, String name )
+ {
+ if( element != null )
+ {
+ builder.append( prefix );
+ if( name != null )
+ {
+ builder.append( name ).append( SQLConstants.TOKEN_SEPARATOR );
+ }
+ processor.process( element, builder );
+ }
+ }
+
+ public static class QueryExpressionBinaryProcessor extends
+ AbstractProcessor<QueryExpressionBodyBinary>
+ {
+ private static final Map<SetOperation, String> _defaultSetOperations;
+
+ static
+ {
+ Map<SetOperation, String> operations = new HashMap<SetOperation, String>();
+ operations.put( SetOperation.EXCEPT, "EXCEPT" );
+ operations.put( SetOperation.INTERSECT, "INTERSECT" );
+ operations.put( SetOperation.UNION, "UNION" );
+ _defaultSetOperations = operations;
+ }
+
+ private final Map<SetOperation, String> _setOperations;
+
+ public QueryExpressionBinaryProcessor()
+ {
+ this( _defaultSetOperations );
+ }
+
+ public QueryExpressionBinaryProcessor( Map<SetOperation, String> setOperations )
+ {
+ super( QueryExpressionBodyBinary.class );
+ Objects.requireNonNull( setOperations, "set operations" );
+ this._setOperations = setOperations;
+ }
+
+ @Override
+ protected void doProcess( SQLProcessorAggregator processor, QueryExpressionBodyBinary body,
+ StringBuilder builder )
+ {
+ Boolean leftIsNotEmpty =
+ body.getLeft() != QueryExpressionBody.EmptyQueryExpressionBody.INSTANCE;
+ if( leftIsNotEmpty )
+ {
+ builder.append( SQLConstants.OPEN_PARENTHESIS );
+ processor.process( body.getLeft(), builder );
+ builder.append( SQLConstants.CLOSE_PARENTHESIS ).append( SQLConstants.NEWLINE );
+ this.processSetOperation( body.getSetOperation(), builder );
+
+ builder.append( SQLConstants.TOKEN_SEPARATOR );
+ ProcessorUtils.processSetQuantifier( body.getSetQuantifier(), builder );
+
+ CorrespondingSpec correspondingCols = body.getCorrespondingColumns();
+ if( correspondingCols != null )
+ {
+ builder.append( SQLConstants.TOKEN_SEPARATOR );
+ processor.process( correspondingCols, builder );
+ }
+
+ builder.append( SQLConstants.NEWLINE ).append( SQLConstants.OPEN_PARENTHESIS );
+ }
+ processor.process( body.getRight(), builder );
+ if( leftIsNotEmpty )
+ {
+ builder.append( SQLConstants.CLOSE_PARENTHESIS );
+ }
+ }
+
+ protected void processSetOperation( SetOperation operation, StringBuilder builder )
+ {
+ builder.append( this._setOperations.get( operation ) );
+ }
+ }
+
+ public static class QuerySpecificationProcessor extends AbstractProcessor<QuerySpecification>
+ {
+
+ public QuerySpecificationProcessor()
+ {
+ this( QuerySpecification.class );
+ }
+
+ public QuerySpecificationProcessor( Class<? extends QuerySpecification> queryClass )
+ {
+ super( queryClass );
+ }
+
+ @Override
+ protected void doProcess( SQLProcessorAggregator processor, QuerySpecification query,
+ StringBuilder builder )
+ {
+ builder.append( SQLConstants.SELECT ).append( SQLConstants.TOKEN_SEPARATOR );
+ ProcessorUtils.processSetQuantifier( query.getColumns().getSetQuantifier(), builder );
+ builder.append( SQLConstants.TOKEN_SEPARATOR );
+
+ processor.process( query.getColumns(), builder );
+ processor.process( query.getFrom(), builder );
+ QueryProcessing.processOptionalBooleanExpression( processor, builder, query.getWhere(),
+ SQLConstants.NEWLINE, SQLConstants.WHERE );
+ processor.process( query.getGroupBy(), builder );
+ QueryProcessing.processOptionalBooleanExpression( processor, builder,
+ query.getHaving(),
+ SQLConstants.NEWLINE, SQLConstants.HAVING );
+ processor.process( query.getOrderBy(), builder );
+ Typeable<?> first = null;
+ Typeable<?> second = null;
+ if( this.isOffsetBeforeLimit( processor ) )
+ {
+ first = query.getOffsetSpecification();
+ second = query.getLimitSpecification();
+ }
+ else
+ {
+ first = query.getLimitSpecification();
+ second = query.getOffsetSpecification();
+ }
+
+ if( first != null || second != null )
+ {
+ this.processLimitAndOffset( processor, builder, first, second );
+ }
+
+ if( query.getOrderBy() == null
+ && ( query.getOffsetSpecification() != null || query.getLimitSpecification() != null ) )
+ {
+ LoggerFactory.getLogger( this.getClass().getName() ).warn(
+ "Spotted query with " + SQLConstants.OFFSET_PREFIX + " and/or "
+ + SQLConstants.LIMIT_PREFIX
+ + " clause, but without ORDER BY. The result will be unpredictable!"
+ + "\n" + "Query: "
+ + builder.toString() );
+ }
+ }
+
+ protected boolean isOffsetBeforeLimit( SQLProcessorAggregator processor )
+ {
+ return true;
+ }
+
+ protected void processLimitAndOffset( SQLProcessorAggregator processor,
+ StringBuilder builder,
+ Typeable<?> first, Typeable<?> second )
+ {
+ QueryProcessing.processOptional( processor, builder, first, SQLConstants.NEWLINE, null );
+ QueryProcessing
+ .processOptional( processor, builder, second, SQLConstants.NEWLINE, null );
+ }
+ }
+
+ public static class SelectColumnsProcessor extends AbstractProcessor<SelectColumnClause>
+ {
+ public SelectColumnsProcessor()
+ {
+ super( SelectColumnClause.class );
+ }
+
+ @Override
+ protected void doProcess( SQLProcessorAggregator aggregator, SelectColumnClause select,
+ StringBuilder builder )
+ {
+ if( select instanceof ColumnReferences )
+ {
+ Iterator<ColumnReferenceInfo> iter =
+ ( (ColumnReferences) select ).getColumns().iterator();
+ while( iter.hasNext() )
+ {
+ ColumnReferenceInfo info = iter.next();
+ aggregator.process( info.getReference(), builder );
+ String alias = info.getAlias();
+ if( ProcessorUtils.notNullAndNotEmpty( alias ) )
+ {
+ builder.append( SQLConstants.TOKEN_SEPARATOR )
+ .append( SQLConstants.ALIAS_DEFINER )
+ .append( SQLConstants.TOKEN_SEPARATOR ).append( alias );
+ }
+
+ if( iter.hasNext() )
+ {
+ builder.append( SQLConstants.COMMA ).append( SQLConstants.TOKEN_SEPARATOR );
+ }
+ }
+ }
+ else
+ {
+ builder.append( SQLConstants.ASTERISK );
+ }
+ }
+ }
+
+ public static class FromProcessor extends AbstractProcessor<FromClause>
+ {
+ public FromProcessor()
+ {
+ super( FromClause.class );
+ }
+
+ @Override
+ protected void doProcess( SQLProcessorAggregator aggregator, FromClause from,
+ StringBuilder builder )
+ {
+ if( !from.getTableReferences().isEmpty() )
+ {
+ builder.append( SQLConstants.NEWLINE ).append( SQLConstants.FROM )
+ .append( SQLConstants.TOKEN_SEPARATOR );
+ Iterator<TableReference> iter = from.getTableReferences().iterator();
+ while( iter.hasNext() )
+ {
+ aggregator.process( iter.next().asTypeable(), builder );
+ if( iter.hasNext() )
+ {
+ builder.append( SQLConstants.COMMA ).append( SQLConstants.TOKEN_SEPARATOR );
+ }
+ }
+ }
+ }
+ }
+
+ public static class QueryExpressionProcessor extends AbstractProcessor<QueryExpression>
+ {
+ public QueryExpressionProcessor()
+ {
+ super( QueryExpression.class );
+ }
+
+ @Override
+ protected void doProcess( SQLProcessorAggregator processor, QueryExpression object,
+ StringBuilder builder )
+ {
+ processor.process( object.getQueryExpressionBody(), builder );
+ }
+ }
+
+ public static class CorrespondingSpecProcessor extends AbstractProcessor<CorrespondingSpec>
+ {
+ public CorrespondingSpecProcessor()
+ {
+ super( CorrespondingSpec.class );
+ }
+
+ @Override
+ protected void doProcess( SQLProcessorAggregator processor, CorrespondingSpec object,
+ StringBuilder builder )
+ {
+ builder.append( "CORRESPONDING" );
+ if( object.getColumnList() != null )
+ {
+ builder.append( SQLConstants.TOKEN_SEPARATOR ).append( "BY" )
+ .append( SQLConstants.TOKEN_SEPARATOR );
+ processor.process( object.getColumnList(), builder );
+ }
+ }
+ }
+
+ public static class SortSpecificationProcessor extends AbstractProcessor<SortSpecification>
+ {
+ private static final Map<Ordering, String> _defaultOrderingStrings;
+
+ static
+ {
+ Map<Ordering, String> map = new HashMap<Ordering, String>();
+ map.put( Ordering.ASCENDING, "ASC" );
+ map.put( Ordering.DESCENDING, "DESC" );
+ _defaultOrderingStrings = map;
+ }
+
+ private final Map<Ordering, String> _orderingStrings;
+
+ public SortSpecificationProcessor()
+ {
+ this( _defaultOrderingStrings );
+ }
+
+ public SortSpecificationProcessor( Map<Ordering, String> orderingStrings )
+ {
+ super( SortSpecification.class );
+ Objects.requireNonNull( orderingStrings, "ordering strings" );
+ this._orderingStrings = orderingStrings;
+ }
+
+ @Override
+ protected void doProcess( SQLProcessorAggregator processor, SortSpecification object,
+ StringBuilder builder )
+ {
+ processor.process( object.getValueExpression(), builder );
+ builder.append( SQLConstants.TOKEN_SEPARATOR ).append(
+ this._orderingStrings.get( object.getOrderingSpecification() ) );
+ }
+ }
+
+ public static class OrdinaryGroupingSetProcessor extends AbstractProcessor<OrdinaryGroupingSet>
+ {
+ public OrdinaryGroupingSetProcessor()
+ {
+ super( OrdinaryGroupingSet.class );
+ }
+
+ @Override
+ protected void doProcess( SQLProcessorAggregator processor, OrdinaryGroupingSet object,
+ StringBuilder builder )
+ {
+ Iterator<NonBooleanExpression> iter = object.getColumns().iterator();
+ while( iter.hasNext() )
+ {
+ processor.process( iter.next(), builder );
+ if( iter.hasNext() )
+ {
+ builder.append( SQLConstants.COMMA ).append( SQLConstants.TOKEN_SEPARATOR );
+ }
+ }
+ }
+ }
+
+ public static class GroupByProcessor extends AbstractProcessor<GroupByClause>
+ {
+ public GroupByProcessor()
+ {
+ super( GroupByClause.class );
+ }
+
+ @Override
+ protected void doProcess( SQLProcessorAggregator aggregator, GroupByClause groupBy,
+ StringBuilder builder )
+ {
+ if( !groupBy.getGroupingElements().isEmpty() )
+ {
+ builder.append( SQLConstants.NEWLINE ).append( SQLConstants.GROUP_BY )
+ .append( SQLConstants.TOKEN_SEPARATOR );
+ Iterator<GroupingElement> iter = groupBy.getGroupingElements().iterator();
+ while( iter.hasNext() )
+ {
+ aggregator.process( iter.next(), builder );
+ if( iter.hasNext() )
+ {
+ builder.append( SQLConstants.COMMA ).append( SQLConstants.TOKEN_SEPARATOR );
+ }
+ }
+ }
+ }
+ }
+
+ public static class OrderByProcessor extends AbstractProcessor<OrderByClause>
+ {
+ public OrderByProcessor()
+ {
+ super( OrderByClause.class );
+ }
+
+ @Override
+ protected void doProcess( SQLProcessorAggregator aggregator, OrderByClause orderBy,
+ StringBuilder builder )
+ {
+ if( !orderBy.getOrderingColumns().isEmpty() )
+ {
+ builder.append( SQLConstants.NEWLINE ).append( SQLConstants.ORDER_BY )
+ .append( SQLConstants.TOKEN_SEPARATOR );
+ Iterator<SortSpecification> iter = orderBy.getOrderingColumns().iterator();
+ while( iter.hasNext() )
+ {
+ aggregator.process( iter.next(), builder );
+ if( iter.hasNext() )
+ {
+ builder.append( SQLConstants.COMMA ).append( SQLConstants.TOKEN_SEPARATOR );
+ }
+ }
+ }
+ }
+ }
+
+ public static class TableValueConstructorProcessor extends
+ AbstractProcessor<TableValueConstructor>
+ {
+ public TableValueConstructorProcessor()
+ {
+ super( TableValueConstructor.class );
+ }
+
+ @Override
+ protected void doProcess( SQLProcessorAggregator aggregator, TableValueConstructor object,
+ StringBuilder builder )
+ {
+ builder.append( "VALUES" ).append( SQLConstants.TOKEN_SEPARATOR );
+ Iterator<RowValueConstructor> iter = object.getRows().iterator();
+ while( iter.hasNext() )
+ {
+ aggregator.process( iter.next(), builder );
+ if( iter.hasNext() )
+ {
+ builder.append( SQLConstants.COMMA ).append( SQLConstants.TOKEN_SEPARATOR );
+ }
+ }
+ }
+ }
+
+ public static class RowSubQueryProcessor extends AbstractProcessor<RowSubQuery>
+ {
+ public RowSubQueryProcessor()
+ {
+ super( RowSubQuery.class );
+ }
+
+ @Override
+ protected void doProcess( SQLProcessorAggregator aggregator, RowSubQuery object,
+ StringBuilder builder )
+ {
+ builder.append( SQLConstants.OPEN_PARENTHESIS );
+ aggregator.process( object.getQueryExpression(), builder );
+ builder.append( SQLConstants.CLOSE_PARENTHESIS );
+ }
+ }
+
+ public static class RowDefinitionProcessor extends AbstractProcessor<RowDefinition>
+ {
+ public RowDefinitionProcessor()
+ {
+ super( RowDefinition.class );
+ }
+
+ @Override
+ protected void doProcess( SQLProcessorAggregator aggregator, RowDefinition object,
+ StringBuilder builder )
+ {
+ builder.append( SQLConstants.OPEN_PARENTHESIS );
+ Iterator<ValueExpression> vals = object.getRowElements().iterator();
+ while( vals.hasNext() )
+ {
+ aggregator.process( vals.next(), builder );
+ if( vals.hasNext() )
+ {
+ builder.append( SQLConstants.COMMA ).append( SQLConstants.TOKEN_SEPARATOR );
+ }
+ }
+ builder.append( SQLConstants.CLOSE_PARENTHESIS );
+ }
+ }
+
+ public static class OffsetSpecificationProcessor extends AbstractProcessor<OffsetSpecification>
+ {
+
+ public OffsetSpecificationProcessor()
+ {
+ super( OffsetSpecification.class );
+ }
+
+ @Override
+ protected void doProcess( SQLProcessorAggregator aggregator, OffsetSpecification object,
+ StringBuilder builder )
+ {
+ String prefix = this.getPrefix( aggregator );
+ if( prefix != null )
+ {
+ builder.append( prefix ).append( SQLConstants.TOKEN_SEPARATOR );
+ }
+ NonBooleanExpression skip = object.getSkip();
+ boolean isComplex = !( skip instanceof LiteralExpression );
+ if( isComplex )
+ {
+ builder.append( SQLConstants.OPEN_PARENTHESIS ).append( SQLConstants.NEWLINE );
+ }
+ aggregator.process( skip, builder );
+ if( isComplex )
+ {
+ builder.append( SQLConstants.CLOSE_PARENTHESIS );
+ }
+ String postfix = this.getPostfix( aggregator );
+ if( postfix != null )
+ {
+ builder.append( SQLConstants.TOKEN_SEPARATOR ).append( postfix );
+ }
+ }
+
+ protected String getPrefix( SQLProcessorAggregator processor )
+ {
+ return SQLConstants.OFFSET_PREFIX;
+ }
+
+ protected String getPostfix( SQLProcessorAggregator processor )
+ {
+ return SQLConstants.OFFSET_POSTFIX;
+ }
+ }
+
+ public static class LimitSpecificationProcessor extends AbstractProcessor<LimitSpecification>
+ {
+ public LimitSpecificationProcessor()
+ {
+ super( LimitSpecification.class );
+ }
+
+ @Override
+ protected void doProcess( SQLProcessorAggregator aggregator, LimitSpecification object,
+ StringBuilder builder )
+ {
+ NonBooleanExpression count = this.getRealCount( object.getCount() );
+ if( count != null )
+ {
+ String prefix = this.getPrefix( aggregator );
+ if( prefix != null )
+ {
+ builder.append( prefix ).append( SQLConstants.TOKEN_SEPARATOR );
+ }
+ boolean isComplex = !( count instanceof LiteralExpression );
+ if( isComplex )
+ {
+ builder.append( SQLConstants.OPEN_PARENTHESIS ).append( SQLConstants.NEWLINE );
+ }
+ aggregator.process( count, builder );
+ if( isComplex )
+ {
+ builder.append( SQLConstants.CLOSE_PARENTHESIS );
+ }
+ String postfix = this.getPostfix( aggregator );
+ if( postfix != null )
+ {
+ builder.append( SQLConstants.TOKEN_SEPARATOR ).append( postfix );
+ }
+ }
+ }
+
+ protected NonBooleanExpression getRealCount( NonBooleanExpression limitCount )
+ {
+ return limitCount;
+ }
+
+ protected String getPrefix( SQLProcessorAggregator processor )
+ {
+ return SQLConstants.LIMIT_PREFIX;
+ }
+
+ protected String getPostfix( SQLProcessorAggregator processor )
+ {
+ return SQLConstants.LIMIT_POSTFIX;
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/polygene-java/blob/a36086b6/libraries/sql-generator/src/main/java/org/apache/polygene/library/sql/generator/implementation/transformation/TableReferenceProcessing.java
----------------------------------------------------------------------
diff --git a/libraries/sql-generator/src/main/java/org/apache/polygene/library/sql/generator/implementation/transformation/TableReferenceProcessing.java b/libraries/sql-generator/src/main/java/org/apache/polygene/library/sql/generator/implementation/transformation/TableReferenceProcessing.java
new file mode 100644
index 0000000..151b4f7
--- /dev/null
+++ b/libraries/sql-generator/src/main/java/org/apache/polygene/library/sql/generator/implementation/transformation/TableReferenceProcessing.java
@@ -0,0 +1,354 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *
+ */
+package org.apache.polygene.library.sql.generator.implementation.transformation;
+
+import org.apache.polygene.library.sql.generator.grammar.common.SQLConstants;
+import org.apache.polygene.library.sql.generator.grammar.common.TableName;
+import org.apache.polygene.library.sql.generator.grammar.common.TableNameDirect;
+import org.apache.polygene.library.sql.generator.grammar.common.TableNameFunction;
+import org.apache.polygene.library.sql.generator.grammar.query.TableAlias;
+import org.apache.polygene.library.sql.generator.grammar.query.TableReferenceByExpression;
+import org.apache.polygene.library.sql.generator.grammar.query.TableReferenceByName;
+import org.apache.polygene.library.sql.generator.grammar.query.TableReferencePrimary;
+import org.apache.polygene.library.sql.generator.grammar.query.joins.CrossJoinedTable;
+import org.apache.polygene.library.sql.generator.grammar.query.joins.JoinCondition;
+import org.apache.polygene.library.sql.generator.grammar.query.joins.JoinType;
+import org.apache.polygene.library.sql.generator.grammar.query.joins.JoinedTable;
+import org.apache.polygene.library.sql.generator.grammar.query.joins.NamedColumnsJoin;
+import org.apache.polygene.library.sql.generator.grammar.query.joins.NaturalJoinedTable;
+import org.apache.polygene.library.sql.generator.grammar.query.joins.QualifiedJoinedTable;
+import org.apache.polygene.library.sql.generator.grammar.query.joins.UnionJoinedTable;
+import org.apache.polygene.library.sql.generator.implementation.transformation.spi.SQLProcessorAggregator;
+
+/**
+ * @author Stanislav Muhametsin
+ */
+public class TableReferenceProcessing
+{
+
+ public static abstract class AbstractTableNameProcessor<TableNameType extends TableName>
+ extends
+ AbstractProcessor<TableNameType>
+ {
+
+ protected AbstractTableNameProcessor( Class<? extends TableNameType> realType )
+ {
+ super( realType );
+ }
+
+ @Override
+ protected void doProcess( SQLProcessorAggregator processor, TableNameType object,
+ StringBuilder builder )
+ {
+ String schemaName = object.getSchemaName();
+ if( ProcessorUtils.notNullAndNotEmpty( schemaName ) )
+ {
+ builder.append( schemaName ).append( SQLConstants.SCHEMA_TABLE_SEPARATOR );
+ }
+ this.doProcessTableName( processor, object, builder );
+ }
+
+ protected abstract void doProcessTableName( SQLProcessorAggregator processor,
+ TableNameType object,
+ StringBuilder builder );
+ }
+
+ public static class TableNameFunctionProcessor extends
+ AbstractTableNameProcessor<TableNameFunction>
+ {
+
+ public TableNameFunctionProcessor()
+ {
+ this( TableNameFunction.class );
+ }
+
+ protected TableNameFunctionProcessor( Class<? extends TableNameFunction> realType )
+ {
+ super( realType );
+ }
+
+ @Override
+ protected void doProcessTableName( SQLProcessorAggregator processor,
+ TableNameFunction object,
+ StringBuilder builder )
+ {
+ processor.process( object.getFunction(), builder );
+ }
+ }
+
+ public static class TableNameDirectProcessor extends
+ AbstractTableNameProcessor<TableNameDirect>
+ {
+
+ public TableNameDirectProcessor()
+ {
+ this( TableNameDirect.class );
+ }
+
+ protected TableNameDirectProcessor( Class<? extends TableNameDirect> realType )
+ {
+ super( realType );
+ }
+
+ @Override
+ protected void doProcessTableName( SQLProcessorAggregator processor,
+ TableNameDirect object,
+ StringBuilder builder )
+ {
+ builder.append( object.getTableName() );
+ }
+ }
+
+ public static abstract class TableReferencePrimaryProcessor<TableReferenceType extends TableReferencePrimary>
+ extends AbstractProcessor<TableReferenceType>
+ {
+ public TableReferencePrimaryProcessor( Class<TableReferenceType> realType )
+ {
+ super( realType );
+ }
+
+ protected void doProcess( SQLProcessorAggregator processor, TableReferenceType object,
+ StringBuilder builder )
+ {
+ this.doProcessTablePrimary( processor, object, builder );
+ if( object.getTableAlias() != null )
+ {
+ this.processTableAlias( processor, object.getTableAlias(), builder );
+ }
+ }
+
+ protected abstract void doProcessTablePrimary( SQLProcessorAggregator processor,
+ TableReferenceType object,
+ StringBuilder builder );
+
+ protected void processTableAlias( SQLProcessorAggregator processor, TableAlias tableAlias,
+ StringBuilder builder )
+ {
+ String alias = tableAlias.getTableAlias();
+ if( ProcessorUtils.notNullAndNotEmpty( alias ) )
+ {
+ builder.append( SQLConstants.TOKEN_SEPARATOR ).append( SQLConstants.ALIAS_DEFINER )
+ .append( SQLConstants.TOKEN_SEPARATOR ).append( alias );
+
+ if( tableAlias.getColumnAliases() != null )
+ {
+ processor.process( tableAlias.getColumnAliases(), builder );
+ }
+ }
+ }
+ }
+
+ public static class TableReferenceByNameProcessor extends
+ TableReferencePrimaryProcessor<TableReferenceByName>
+ {
+ public TableReferenceByNameProcessor()
+ {
+ super( TableReferenceByName.class );
+ }
+
+ @Override
+ protected void doProcessTablePrimary( SQLProcessorAggregator processor,
+ TableReferenceByName object,
+ StringBuilder builder )
+ {
+ processor.process( object.getTableName(), builder );
+ }
+ }
+
+ public static class TableReferenceByExpressionProcessor extends
+ TableReferencePrimaryProcessor<TableReferenceByExpression>
+ {
+ public TableReferenceByExpressionProcessor()
+ {
+ super( TableReferenceByExpression.class );
+ }
+
+ @Override
+ protected void doProcessTablePrimary( SQLProcessorAggregator processor,
+ TableReferenceByExpression tableRef,
+ StringBuilder builder )
+ {
+ builder.append( SQLConstants.OPEN_PARENTHESIS );
+ processor.process( tableRef.getQuery(), builder );
+ builder.append( SQLConstants.CLOSE_PARENTHESIS );
+ }
+ }
+
+ public static abstract class JoinedTableProcessor<JoinedTableType extends JoinedTable> extends
+ AbstractProcessor<JoinedTableType>
+ {
+
+ public JoinedTableProcessor( Class<JoinedTableType> realType )
+ {
+ super( realType );
+ }
+
+ protected void doProcess( SQLProcessorAggregator processor, JoinedTableType table,
+ StringBuilder builder )
+ {
+ processor.process( table.getLeft().asTypeable(), builder );
+ builder.append( SQLConstants.NEWLINE );
+ this.doProcessJoinedTable( processor, table, builder );
+ }
+
+ protected abstract void doProcessJoinedTable( SQLProcessorAggregator processor,
+ JoinedTableType table,
+ StringBuilder builder );
+
+ protected void processJoinType( JoinType joinType, StringBuilder builder )
+ {
+ if( joinType != null )
+ {
+ if( joinType == JoinType.INNER )
+ {
+ builder.append( "INNER " );
+ }
+ else
+ {
+ if( joinType == JoinType.FULL_OUTER )
+ {
+ builder.append( "FULL " );
+ }
+ else if( joinType == JoinType.LEFT_OUTER )
+ {
+ builder.append( "LEFT " );
+ }
+ else
+ // if (joinType == JoinType.RIGHT_OUTER)
+ {
+ builder.append( "RIGHT " );
+ }
+ }
+ builder.append( "JOIN" ).append( SQLConstants.TOKEN_SEPARATOR );
+ }
+ }
+ }
+
+ public static class CrossJoinedTableProcessor extends JoinedTableProcessor<CrossJoinedTable>
+ {
+ public CrossJoinedTableProcessor()
+ {
+ super( CrossJoinedTable.class );
+ }
+
+ @Override
+ protected void doProcessJoinedTable( SQLProcessorAggregator processor,
+ CrossJoinedTable table,
+ StringBuilder builder )
+ {
+ builder.append( SQLConstants.TOKEN_SEPARATOR ).append( "CROSS JOIN" )
+ .append( SQLConstants.TOKEN_SEPARATOR );
+ processor.process( table.getRight().asTypeable(), builder );
+ }
+ }
+
+ public static class NaturalJoinedTableProcessor extends
+ JoinedTableProcessor<NaturalJoinedTable>
+ {
+ public NaturalJoinedTableProcessor()
+ {
+ super( NaturalJoinedTable.class );
+ }
+
+ @Override
+ protected void doProcessJoinedTable( SQLProcessorAggregator processor,
+ NaturalJoinedTable table,
+ StringBuilder builder )
+ {
+ builder.append( SQLConstants.TOKEN_SEPARATOR ).append( "NATURAL" )
+ .append( SQLConstants.TOKEN_SEPARATOR );
+ this.processJoinType( table.getJoinType(), builder );
+ builder.append( SQLConstants.TOKEN_SEPARATOR );
+ processor.process( table.getRight().asTypeable(), builder );
+ }
+ }
+
+ public static class QualifiedJoinedTableProcessor extends
+ JoinedTableProcessor<QualifiedJoinedTable>
+ {
+ public QualifiedJoinedTableProcessor()
+ {
+ super( QualifiedJoinedTable.class );
+ }
+
+ @Override
+ protected void doProcessJoinedTable( SQLProcessorAggregator processor,
+ QualifiedJoinedTable table,
+ StringBuilder builder )
+ {
+ this.processJoinType( table.getJoinType(), builder );
+ processor.process( table.getRight().asTypeable(), builder );
+ processor.process( table.getJoinSpecification(), builder );
+ }
+ }
+
+ public static class UnionJoinedTableProcessor extends JoinedTableProcessor<UnionJoinedTable>
+ {
+ public UnionJoinedTableProcessor()
+ {
+ super( UnionJoinedTable.class );
+ }
+
+ @Override
+ protected void doProcessJoinedTable( SQLProcessorAggregator processor,
+ UnionJoinedTable table,
+ StringBuilder builder )
+ {
+ builder.append( SQLConstants.TOKEN_SEPARATOR ).append( "UNION JOIN" )
+ .append( SQLConstants.TOKEN_SEPARATOR );
+ processor.process( table.getRight().asTypeable(), builder );
+ }
+ }
+
+ public static class JoinConditionProcessor extends AbstractProcessor<JoinCondition>
+ {
+ public JoinConditionProcessor()
+ {
+ super( JoinCondition.class );
+ }
+
+ @Override
+ protected void doProcess( SQLProcessorAggregator processor, JoinCondition condition,
+ StringBuilder builder )
+ {
+ builder.append( SQLConstants.TOKEN_SEPARATOR ).append( "ON" )
+ .append( SQLConstants.TOKEN_SEPARATOR );
+ processor.process( condition.getSearchConidition(), builder );
+ }
+ }
+
+ public static class NamedColumnsJoinProcessor extends AbstractProcessor<NamedColumnsJoin>
+ {
+ public NamedColumnsJoinProcessor()
+ {
+ super( NamedColumnsJoin.class );
+ }
+
+ @Override
+ protected void doProcess( SQLProcessorAggregator processor, NamedColumnsJoin join,
+ StringBuilder builder )
+ {
+ builder.append( SQLConstants.TOKEN_SEPARATOR ).append( "USING" )
+ .append( SQLConstants.TOKEN_SEPARATOR );
+
+ processor.process( join.getColumnNames(), builder );
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/polygene-java/blob/a36086b6/libraries/sql-generator/src/main/java/org/apache/polygene/library/sql/generator/implementation/transformation/derby/DerbyProcessor.java
----------------------------------------------------------------------
diff --git a/libraries/sql-generator/src/main/java/org/apache/polygene/library/sql/generator/implementation/transformation/derby/DerbyProcessor.java b/libraries/sql-generator/src/main/java/org/apache/polygene/library/sql/generator/implementation/transformation/derby/DerbyProcessor.java
new file mode 100644
index 0000000..afc7d35
--- /dev/null
+++ b/libraries/sql-generator/src/main/java/org/apache/polygene/library/sql/generator/implementation/transformation/derby/DerbyProcessor.java
@@ -0,0 +1,32 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *
+ */
+package org.apache.polygene.library.sql.generator.implementation.transformation.derby;
+
+import org.apache.polygene.library.sql.generator.implementation.transformation.DefaultSQLProcessor;
+import org.apache.polygene.library.sql.generator.vendor.SQLVendor;
+
+public class DerbyProcessor extends DefaultSQLProcessor
+{
+
+ public DerbyProcessor( SQLVendor vendor )
+ {
+ super( vendor, DefaultSQLProcessor.getDefaultProcessors() );
+ }
+}
http://git-wip-us.apache.org/repos/asf/polygene-java/blob/a36086b6/libraries/sql-generator/src/main/java/org/apache/polygene/library/sql/generator/implementation/transformation/h2/H2Processor.java
----------------------------------------------------------------------
diff --git a/libraries/sql-generator/src/main/java/org/apache/polygene/library/sql/generator/implementation/transformation/h2/H2Processor.java b/libraries/sql-generator/src/main/java/org/apache/polygene/library/sql/generator/implementation/transformation/h2/H2Processor.java
new file mode 100644
index 0000000..8176980
--- /dev/null
+++ b/libraries/sql-generator/src/main/java/org/apache/polygene/library/sql/generator/implementation/transformation/h2/H2Processor.java
@@ -0,0 +1,33 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *
+ */
+package org.apache.polygene.library.sql.generator.implementation.transformation.h2;
+
+import org.apache.polygene.library.sql.generator.implementation.transformation.DefaultSQLProcessor;
+import org.apache.polygene.library.sql.generator.vendor.SQLVendor;
+
+public class H2Processor
+ extends DefaultSQLProcessor
+{
+
+ public H2Processor( SQLVendor vendor )
+ {
+ super( vendor, DefaultSQLProcessor.getDefaultProcessors() );
+ }
+}
http://git-wip-us.apache.org/repos/asf/polygene-java/blob/a36086b6/libraries/sql-generator/src/main/java/org/apache/polygene/library/sql/generator/implementation/transformation/mysql/DefinitionProcessing.java
----------------------------------------------------------------------
diff --git a/libraries/sql-generator/src/main/java/org/apache/polygene/library/sql/generator/implementation/transformation/mysql/DefinitionProcessing.java b/libraries/sql-generator/src/main/java/org/apache/polygene/library/sql/generator/implementation/transformation/mysql/DefinitionProcessing.java
new file mode 100644
index 0000000..3ccc96f
--- /dev/null
+++ b/libraries/sql-generator/src/main/java/org/apache/polygene/library/sql/generator/implementation/transformation/mysql/DefinitionProcessing.java
@@ -0,0 +1,54 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *
+ */
+package org.apache.polygene.library.sql.generator.implementation.transformation.mysql;
+
+import org.apache.polygene.library.sql.generator.grammar.definition.schema.SchemaDefinition;
+import org.apache.polygene.library.sql.generator.grammar.definition.table.ColumnDefinition;
+import org.apache.polygene.library.sql.generator.implementation.transformation.DefinitionProcessing.ColumnDefinitionProcessor;
+import org.apache.polygene.library.sql.generator.implementation.transformation.DefinitionProcessing.SchemaDefinitionProcessor;
+import org.apache.polygene.library.sql.generator.implementation.transformation.spi.SQLProcessorAggregator;
+
+/**
+ * @author Stanislav Muhametsin
+ */
+public class DefinitionProcessing
+{
+
+ public static class MySQLSchemaDefinitionProcessor extends SchemaDefinitionProcessor
+ {
+
+ @Override
+ protected void doProcess( SQLProcessorAggregator aggregator, SchemaDefinition object, StringBuilder builder )
+ {
+ // Just process schema elements
+ this.processSchemaElements( aggregator, object, builder );
+ }
+ }
+
+ public static class MySQLColumnDefinitionProcessor extends ColumnDefinitionProcessor
+ {
+ @Override
+ protected void processAutoGenerationPolicy( ColumnDefinition object, StringBuilder builder )
+ {
+ // MySQL combines both ALWAYS and BY DEFAULT policies.
+ builder.append( " AUTO_INCREMENT" );
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/polygene-java/blob/a36086b6/libraries/sql-generator/src/main/java/org/apache/polygene/library/sql/generator/implementation/transformation/mysql/MySQLProcessor.java
----------------------------------------------------------------------
diff --git a/libraries/sql-generator/src/main/java/org/apache/polygene/library/sql/generator/implementation/transformation/mysql/MySQLProcessor.java b/libraries/sql-generator/src/main/java/org/apache/polygene/library/sql/generator/implementation/transformation/mysql/MySQLProcessor.java
new file mode 100644
index 0000000..dc036f6
--- /dev/null
+++ b/libraries/sql-generator/src/main/java/org/apache/polygene/library/sql/generator/implementation/transformation/mysql/MySQLProcessor.java
@@ -0,0 +1,81 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *
+ */
+package org.apache.polygene.library.sql.generator.implementation.transformation.mysql;
+
+import java.util.HashMap;
+import java.util.Map;
+import org.apache.polygene.library.sql.generator.Typeable;
+import org.apache.polygene.library.sql.generator.grammar.common.TableNameDirect;
+import org.apache.polygene.library.sql.generator.grammar.common.TableNameFunction;
+import org.apache.polygene.library.sql.generator.grammar.definition.schema.SchemaDefinition;
+import org.apache.polygene.library.sql.generator.grammar.definition.table.ColumnDefinition;
+import org.apache.polygene.library.sql.generator.grammar.manipulation.DropSchemaStatement;
+import org.apache.polygene.library.sql.generator.grammar.query.LimitSpecification;
+import org.apache.polygene.library.sql.generator.grammar.query.OffsetSpecification;
+import org.apache.polygene.library.sql.generator.grammar.query.QuerySpecification;
+import org.apache.polygene.library.sql.generator.implementation.transformation.DefaultSQLProcessor;
+import org.apache.polygene.library.sql.generator.implementation.transformation.NoOpProcessor;
+import org.apache.polygene.library.sql.generator.implementation.transformation.mysql.DefinitionProcessing.MySQLColumnDefinitionProcessor;
+import org.apache.polygene.library.sql.generator.implementation.transformation.mysql.DefinitionProcessing.MySQLSchemaDefinitionProcessor;
+import org.apache.polygene.library.sql.generator.implementation.transformation.mysql.QueryProcessing.MySQLLimitSpecificationProcessor;
+import org.apache.polygene.library.sql.generator.implementation.transformation.mysql.QueryProcessing.MySQLOffsetSpecificationProcessor;
+import org.apache.polygene.library.sql.generator.implementation.transformation.mysql.QueryProcessing.MySQLQuerySpecificationProcessor;
+import org.apache.polygene.library.sql.generator.implementation.transformation.mysql.TableProcessing.MySQLTableNameDirectProcessor;
+import org.apache.polygene.library.sql.generator.implementation.transformation.mysql.TableProcessing.MySQLTableNameFunctionProcessor;
+import org.apache.polygene.library.sql.generator.implementation.transformation.spi.SQLProcessor;
+import org.apache.polygene.library.sql.generator.vendor.SQLVendor;
+
+/**
+ * @author Stanislav Muhametsin
+ */
+public class MySQLProcessor extends DefaultSQLProcessor
+{
+
+ private static final Map<Class<? extends Typeable<?>>, SQLProcessor> _defaultProcessors;
+
+ static
+ {
+ Map<Class<? extends Typeable<?>>, SQLProcessor> processors = new HashMap<Class<? extends Typeable<?>>, SQLProcessor>(
+ DefaultSQLProcessor.getDefaultProcessors() );
+
+ // MySQL does not understand schema-qualified table names (or anything related to schemas)
+ processors.put( TableNameDirect.class, new MySQLTableNameDirectProcessor() );
+ processors.put( TableNameFunction.class, new MySQLTableNameFunctionProcessor() );
+
+ // Only process schema elements from schema definition, and ignore drop schema statements
+ processors.put( SchemaDefinition.class, new MySQLSchemaDefinitionProcessor() );
+ processors.put( DropSchemaStatement.class, new NoOpProcessor() );
+
+ // Override default column definition support
+ processors.put( ColumnDefinition.class, new MySQLColumnDefinitionProcessor() );
+
+ // Different syntax for OFFSET/FETCH
+ processors.put( QuerySpecification.class, new MySQLQuerySpecificationProcessor() );
+ processors.put( OffsetSpecification.class, new MySQLOffsetSpecificationProcessor() );
+ processors.put( LimitSpecification.class, new MySQLLimitSpecificationProcessor() );
+
+ _defaultProcessors = processors;
+ }
+
+ public MySQLProcessor( SQLVendor vendor )
+ {
+ super( vendor, _defaultProcessors );
+ }
+}
http://git-wip-us.apache.org/repos/asf/polygene-java/blob/a36086b6/libraries/sql-generator/src/main/java/org/apache/polygene/library/sql/generator/implementation/transformation/mysql/QueryProcessing.java
----------------------------------------------------------------------
diff --git a/libraries/sql-generator/src/main/java/org/apache/polygene/library/sql/generator/implementation/transformation/mysql/QueryProcessing.java b/libraries/sql-generator/src/main/java/org/apache/polygene/library/sql/generator/implementation/transformation/mysql/QueryProcessing.java
new file mode 100644
index 0000000..7324418
--- /dev/null
+++ b/libraries/sql-generator/src/main/java/org/apache/polygene/library/sql/generator/implementation/transformation/mysql/QueryProcessing.java
@@ -0,0 +1,114 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *
+ */
+package org.apache.polygene.library.sql.generator.implementation.transformation.mysql;
+
+import org.apache.polygene.library.sql.generator.Typeable;
+import org.apache.polygene.library.sql.generator.grammar.common.SQLConstants;
+import org.apache.polygene.library.sql.generator.grammar.query.LimitSpecification;
+import org.apache.polygene.library.sql.generator.grammar.query.OffsetSpecification;
+import org.apache.polygene.library.sql.generator.implementation.transformation.QueryProcessing.LimitSpecificationProcessor;
+import org.apache.polygene.library.sql.generator.implementation.transformation.QueryProcessing.OffsetSpecificationProcessor;
+import org.apache.polygene.library.sql.generator.implementation.transformation.QueryProcessing.QuerySpecificationProcessor;
+import org.apache.polygene.library.sql.generator.implementation.transformation.spi.SQLProcessorAggregator;
+import org.apache.polygene.library.sql.generator.vendor.MySQLVendor;
+
+/**
+ * @author 2011 Stanislav Muhametsin
+ */
+public class QueryProcessing
+{
+ private static final String MYSQL_LIMIT_PREFIX = "LIMIT";
+ private static final String MYSQL_LIMIT_POSTFIX = null;
+ private static final String MYSQL_OFFSET_PREFIX = "OFFSET";
+ private static final String MYSQL_OFFSET_POSTFIX = null;
+
+ public static class MySQLQuerySpecificationProcessor extends QuerySpecificationProcessor
+ {
+ @Override
+ protected boolean isOffsetBeforeLimit( SQLProcessorAggregator processor )
+ {
+ return false;
+ }
+
+ @Override
+ protected void processLimitAndOffset( SQLProcessorAggregator processor, StringBuilder builder,
+ Typeable<?> first, Typeable<?> second )
+ {
+ MySQLVendor vendor = (MySQLVendor) processor.getVendor();
+ if( vendor.legacyLimit() )
+ {
+ // Just do the processing right away, because of the difference of syntax
+ builder.append( SQLConstants.NEWLINE ).append( MYSQL_LIMIT_PREFIX )
+ .append( SQLConstants.TOKEN_SEPARATOR );
+ if( second != null )
+ {
+ processor.process( ( (OffsetSpecification) second ).getSkip(), builder );
+ builder.append( SQLConstants.COMMA );
+ }
+ if( first != null && ( (LimitSpecification) first ).getCount() != null )
+ {
+ processor.process( ( (LimitSpecification) first ).getCount(), builder );
+ }
+ else if( second != null )
+ {
+ builder.append( Long.MAX_VALUE );
+ }
+ }
+ else
+ {
+ if( first == null && second != null )
+ {
+ first = vendor.getQueryFactory().limit( vendor.getLiteralFactory().n( Long.MAX_VALUE ) );
+ }
+ super.processLimitAndOffset( processor, builder, first, second );
+ }
+ }
+ }
+
+ public static class MySQLOffsetSpecificationProcessor extends OffsetSpecificationProcessor
+ {
+ @Override
+ protected String getPrefix( SQLProcessorAggregator processor )
+ {
+ return MYSQL_OFFSET_PREFIX;
+ }
+
+ @Override
+ protected String getPostfix( SQLProcessorAggregator processor )
+ {
+ return MYSQL_OFFSET_POSTFIX;
+ }
+ }
+
+ public static class MySQLLimitSpecificationProcessor extends LimitSpecificationProcessor
+ {
+ @Override
+ protected String getPrefix( SQLProcessorAggregator processor )
+ {
+ return MYSQL_LIMIT_PREFIX;
+ }
+
+ @Override
+ protected String getPostfix( SQLProcessorAggregator processor )
+ {
+ return MYSQL_LIMIT_POSTFIX;
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/polygene-java/blob/a36086b6/libraries/sql-generator/src/main/java/org/apache/polygene/library/sql/generator/implementation/transformation/mysql/TableProcessing.java
----------------------------------------------------------------------
diff --git a/libraries/sql-generator/src/main/java/org/apache/polygene/library/sql/generator/implementation/transformation/mysql/TableProcessing.java b/libraries/sql-generator/src/main/java/org/apache/polygene/library/sql/generator/implementation/transformation/mysql/TableProcessing.java
new file mode 100644
index 0000000..e209b07
--- /dev/null
+++ b/libraries/sql-generator/src/main/java/org/apache/polygene/library/sql/generator/implementation/transformation/mysql/TableProcessing.java
@@ -0,0 +1,52 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *
+ */
+package org.apache.polygene.library.sql.generator.implementation.transformation.mysql;
+
+import org.apache.polygene.library.sql.generator.grammar.common.TableNameDirect;
+import org.apache.polygene.library.sql.generator.grammar.common.TableNameFunction;
+import org.apache.polygene.library.sql.generator.implementation.transformation.TableReferenceProcessing.TableNameDirectProcessor;
+import org.apache.polygene.library.sql.generator.implementation.transformation.TableReferenceProcessing.TableNameFunctionProcessor;
+import org.apache.polygene.library.sql.generator.implementation.transformation.spi.SQLProcessorAggregator;
+
+/**
+ * @author Stanislav Muhametsin
+ */
+public class TableProcessing
+{
+ public static class MySQLTableNameDirectProcessor extends TableNameDirectProcessor
+ {
+ @Override
+ protected void doProcess( SQLProcessorAggregator processor, TableNameDirect object, StringBuilder builder )
+ {
+ // MySQL does not understand schema-qualified table names
+ builder.append( object.getTableName() );
+ }
+ }
+
+ public static class MySQLTableNameFunctionProcessor extends TableNameFunctionProcessor
+ {
+ @Override
+ protected void doProcess( SQLProcessorAggregator processor, TableNameFunction object, StringBuilder builder )
+ {
+ // MySQL does not understand schema-qualified table names
+ processor.process( object.getFunction(), builder );
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/polygene-java/blob/a36086b6/libraries/sql-generator/src/main/java/org/apache/polygene/library/sql/generator/implementation/transformation/package-info.java
----------------------------------------------------------------------
diff --git a/libraries/sql-generator/src/main/java/org/apache/polygene/library/sql/generator/implementation/transformation/package-info.java b/libraries/sql-generator/src/main/java/org/apache/polygene/library/sql/generator/implementation/transformation/package-info.java
new file mode 100644
index 0000000..1560a29
--- /dev/null
+++ b/libraries/sql-generator/src/main/java/org/apache/polygene/library/sql/generator/implementation/transformation/package-info.java
@@ -0,0 +1,23 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *
+ */
+/**
+ * This package contains the default processors for syntax elements defined in API. The vendor uses these processors (or custom processors) to create textual SQL statement out of API syntax elements.
+ */
+package org.apache.polygene.library.sql.generator.implementation.transformation;
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/polygene-java/blob/a36086b6/libraries/sql-generator/src/main/java/org/apache/polygene/library/sql/generator/implementation/transformation/pgsql/DefinitionProcessing.java
----------------------------------------------------------------------
diff --git a/libraries/sql-generator/src/main/java/org/apache/polygene/library/sql/generator/implementation/transformation/pgsql/DefinitionProcessing.java b/libraries/sql-generator/src/main/java/org/apache/polygene/library/sql/generator/implementation/transformation/pgsql/DefinitionProcessing.java
new file mode 100644
index 0000000..2eb78fa
--- /dev/null
+++ b/libraries/sql-generator/src/main/java/org/apache/polygene/library/sql/generator/implementation/transformation/pgsql/DefinitionProcessing.java
@@ -0,0 +1,90 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *
+ */
+package org.apache.polygene.library.sql.generator.implementation.transformation.pgsql;
+
+import java.util.Map;
+import java.util.Objects;
+import org.apache.polygene.library.sql.generator.grammar.definition.table.AutoGenerationPolicy;
+import org.apache.polygene.library.sql.generator.grammar.definition.table.ColumnDefinition;
+import org.apache.polygene.library.sql.generator.implementation.transformation.DefinitionProcessing.ColumnDefinitionProcessor;
+import org.apache.polygene.library.sql.generator.implementation.transformation.spi.SQLProcessorAggregator;
+
+/**
+ * @author Stanislav Muhametsin
+ */
+public class DefinitionProcessing
+{
+ public static class PGColumnDefinitionProcessor extends ColumnDefinitionProcessor
+ {
+ private final Map<Class<?>, String> _dataTypeSerialNames;
+
+ public PGColumnDefinitionProcessor( Map<Class<?>, String> dataTypeSerialNames )
+ {
+ Objects.requireNonNull( dataTypeSerialNames, "Data type serial names" );
+ this._dataTypeSerialNames = dataTypeSerialNames;
+ }
+
+ @Override
+ protected void processDataType( SQLProcessorAggregator aggregator, ColumnDefinition object,
+ StringBuilder builder )
+ {
+ AutoGenerationPolicy autoGenPolicy = object.getAutoGenerationPolicy();
+ if( autoGenPolicy == null )
+ {
+ super.processDataType( aggregator, object, builder );
+ }
+ else
+ {
+ // PostgreSQL can't handle the ALWAYS strategy
+ if( AutoGenerationPolicy.BY_DEFAULT.equals( autoGenPolicy ) )
+ {
+ // Don't produce default data type if auto generated
+ Class<?> dtClass = object.getDataType().getClass();
+ Boolean success = false;
+ for( Map.Entry<Class<?>, String> entry : this._dataTypeSerialNames.entrySet() )
+ {
+ success = entry.getKey().isAssignableFrom( dtClass );
+ if( success )
+ {
+ builder.append( entry.getValue() );
+ break;
+ }
+ }
+ if( !success )
+ {
+ throw new UnsupportedOperationException( "Unsupported column data type " + object.getDataType()
+ + " for auto-generated column." );
+ }
+ }
+ else
+ {
+ throw new UnsupportedOperationException( "Unsupported auto generation policy: " + autoGenPolicy
+ + "." );
+ }
+ }
+ }
+
+ @Override
+ protected void processAutoGenerationPolicy( ColumnDefinition object, StringBuilder builder )
+ {
+ // Nothing to do - auto generation policy handled in data type orc
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/polygene-java/blob/a36086b6/libraries/sql-generator/src/main/java/org/apache/polygene/library/sql/generator/implementation/transformation/pgsql/LiteralExpressionProcessing.java
----------------------------------------------------------------------
diff --git a/libraries/sql-generator/src/main/java/org/apache/polygene/library/sql/generator/implementation/transformation/pgsql/LiteralExpressionProcessing.java b/libraries/sql-generator/src/main/java/org/apache/polygene/library/sql/generator/implementation/transformation/pgsql/LiteralExpressionProcessing.java
new file mode 100644
index 0000000..de1dae7
--- /dev/null
+++ b/libraries/sql-generator/src/main/java/org/apache/polygene/library/sql/generator/implementation/transformation/pgsql/LiteralExpressionProcessing.java
@@ -0,0 +1,40 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *
+ */
+package org.apache.polygene.library.sql.generator.implementation.transformation.pgsql;
+
+import org.apache.polygene.library.sql.generator.grammar.literals.TimestampTimeLiteral;
+import org.apache.polygene.library.sql.generator.implementation.transformation.LiteralExpressionProcessing.DateTimeLiteralProcessor;
+import org.apache.polygene.library.sql.generator.implementation.transformation.spi.SQLProcessorAggregator;
+
+/**
+ * @author Stanislav Muhametsin
+ */
+public class LiteralExpressionProcessing
+{
+ public static class PGDateTimeLiteralProcessor extends DateTimeLiteralProcessor
+ {
+ @Override
+ protected void doProcess( SQLProcessorAggregator processor, TimestampTimeLiteral object, StringBuilder builder )
+ {
+ builder.append( "timestamp " );
+ super.doProcess( processor, object, builder );
+ }
+ }
+}