Revision 46505 trunk/org.gvsig.desktop/org.gvsig.desktop.compat.cdc/org.gvsig.fmap.dal/org.gvsig.fmap.dal.db/org.gvsig.fmap.dal.db.jdbc/src/main/java/org/gvsig/fmap/dal/store/jdbc2/spi/JDBCHelperBase.java

View differences:

JDBCHelperBase.java
27 27
import java.sql.Blob;
28 28
import java.sql.Clob;
29 29
import java.sql.ResultSet;
30
import java.sql.ResultSetMetaData;
30 31
import java.util.ArrayList;
32
import java.util.Collections;
33
import java.util.HashMap;
31 34
import java.util.HashSet;
32 35
import java.util.List;
36
import java.util.Map;
33 37
import java.util.function.Predicate;
34 38
import org.apache.commons.io.IOUtils;
35 39
import org.apache.commons.lang3.ArrayUtils;
......
97 101
import org.slf4j.LoggerFactory;
98 102
import static org.gvsig.expressionevaluator.ExpressionBuilder.FUNCTION_$CONSTANT;
99 103
import static org.gvsig.expressionevaluator.ExpressionBuilder.FUNCTION_$IDENTIFIER;
104
import org.gvsig.fmap.dal.DataManager;
105
import org.gvsig.fmap.dal.SQLBuilder.Column;
106
import org.gvsig.fmap.dal.SQLBuilder.OrderByBuilder;
107
import org.gvsig.fmap.dal.SQLBuilder.SelectBuilder;
108
import org.gvsig.fmap.dal.SQLBuilder.SelectColumnBuilder;
100 109
import org.gvsig.fmap.dal.store.jdbc2.JDBCConnection;
101 110
import org.gvsig.fmap.dal.store.jdbc2.spi.expressionbuilder.formatters.ComputedAttribute;
102 111
import org.gvsig.tools.util.ContainerUtils;
......
107 116
  private static final boolean ALLOW_AUTOMATIC_VALUES = true;
108 117
  private static final String QUOTE_FOR_USE_IN_IDENTIFIERS = "\"";
109 118
  private static final String QUOTE_FOR_USE_IN_STRINGS = "'";
119
  public static final String DONT_ADD_TABLE_NAME_TO_COLUMNS = "DONT_ADD_TABLE_NAME";
110 120

  
111 121
  private static final Logger LOGGER = LoggerFactory.getLogger(JDBCHelperBase.class);
112 122

  
......
699 709
          List<String> extra_column_names) {
700 710
    replaceForeingValueFunction(sqlbuilder, type, extra_column_names);
701 711
    replaceExistsFunction(sqlbuilder, type, extra_column_names);
712
    addTableToColumnReferences(sqlbuilder, type);
702 713
  }
703 714

  
704 715
  @SuppressWarnings("Convert2Lambda")
......
870 881
        if (ContainerUtils.contains(extra_column_names, variable.name(), ContainerUtils.EQUALS_IGNORECASE_COMPARATOR)) {
871 882
            continue;
872 883
        }
884
        boolean alreadyReplaced = false;
873 885
        for (String foreingName : foreing_value_args) {
874 886
          String[] foreingNameParts = foreingName.split("[.]");
875 887
          if (foreingNameParts.length != 2) {
......
878 890
          String columnNameLocal = foreingNameParts[0];
879 891
          String columnNameForeing = foreingNameParts[1];
880 892
          if (StringUtils.equalsIgnoreCase(variable.name(), columnNameForeing)) {
893
              if(alreadyReplaced){
894
                  throw new RuntimeException("Column reference \""+ columnNameForeing+"\" is ambiguous");
895
              }
896
              alreadyReplaced = true;
881 897
              
882 898
              FeatureAttributeDescriptor attr = type.getAttributeDescriptor(columnNameLocal);
883 899
              if (attr == null) {
......
960 976
                    );
961 977
            usedLeftJoins.add(foreingTable.getName());
962 978
          }
963
          if ( !(sqlbuilder.select().has_group_by() || sqlbuilder.select().has_aggregate_functions()) ) {
964
                sqlbuilder.select().column().name(foreingTable, columnNameForeing);
965
          }
979
          //No est? claro si debe a?adirse esta columna o no, OJO quitarlo o ponerlo altera los test de  H2
980
//          if ( !(sqlbuilder.select().has_group_by() || sqlbuilder.select().has_aggregate_functions()) ) {
981
//                sqlbuilder.select().column().name(foreingTable, columnNameForeing);
982
//          }
966 983
        }
967 984
      }
968 985
      
969
        for (SQLBuilder.SelectColumnBuilder column : sqlbuilder.select().getColumns()) {
970
            if(column.getTable()==null && column.getName()!=null) {
971
                column.name(table, column.getName());
972
            }
973
        }
974

  
975 986
    } catch (Throwable th) {
976 987
      LOGGER.warn("Can't replace FOREING_VALUE function.", th);
977 988
      throw th;
......
979 990
//      LOGGER.trace("Exit from replaceForeingValueFunction.");
980 991
    }
981 992
  }
993
 
994
    protected void addTableToColumnReferences(SQLBuilder sqlbuilder, FeatureType type) {
995
//        List<SelectBuilder> selectBuilders = new ArrayList<>();
996
//        selectBuilders.add(sqlbuilder.select());
997
//        sqlbuilder.select().accept((ExpressionBuilder.Visitable value) -> {
998
//            selectBuilders.add((SelectBuilder) value);
999
//
1000
//        }, (ExpressionBuilder.Visitable visitable) -> (visitable instanceof SelectBuilder));
1001
//        for (SelectBuilder selectBuilder : selectBuilders) {
1002
//            addTableToColumnReferencesInSingleSelect(sqlbuilder, selectBuilder);
1003
//        }
982 1004

  
1005

  
1006
        addTableToColumnReferencesInSingleSelect(sqlbuilder, sqlbuilder.select(), new ArrayList<>());
1007
        
1008
    }
1009
    
1010
    protected void addTableToColumnReferencesInSingleSelect(SQLBuilder sqlbuilder, SelectBuilder select, List<Column> parentColumns) {
1011
        
1012
        final SQLBuilder.TableNameBuilder table = select.from().table();
1013

  
1014
        final List<ExpressionBuilder.Value[]> value_replacements = new ArrayList<>();
1015
        List<ExpressionBuilder.Variable> variables = new ArrayList<>();
1016
        List<ExpressionBuilder.Value> variablesToExclude = new ArrayList<>();
1017
        
1018
        select.accept((ExpressionBuilder.Visitable value) -> {
1019
            if(value instanceof ExpressionBuilder.Function) {
1020
                ExpressionBuilder.Function fn = (ExpressionBuilder.Function) value;
1021
                if(StringUtils.equals(fn.name(), ExpressionBuilder.FUNCTION_GETATTR)){
1022
                    ExpressionBuilder.Value p1 = fn.parameters().get(0);
1023
                    if(p1 instanceof ExpressionBuilder.Variable){
1024
                        ExpressionBuilder.Variable v = (ExpressionBuilder.Variable) p1;
1025
                        variablesToExclude.add(v);
1026
                    }
1027
                    ExpressionBuilder.Value p2 = fn.parameters().get(1);
1028
                    if(p2 instanceof ExpressionBuilder.Constant){
1029
                        ExpressionBuilder.Constant c = (ExpressionBuilder.Constant) p2;
1030
                        variablesToExclude.add(c);
1031
                    }
1032
                }
1033
            } else if(value instanceof Column) {
1034
                Column c = (Column)value;
1035
                if(c.table() == null || !c.table().has_name()){
1036
                    variables.add(c);
1037
                }
1038
                
1039
            } else if(value instanceof ExpressionBuilder.Variable) {
1040
                variables.add((ExpressionBuilder.Variable) value);
1041
//            } else if(value instanceof SelectColumnBuilder) {
1042
//                SelectColumnBuilder selectColumn = (SelectColumnBuilder)value;
1043
//                if(StringUtils.isNotBlank(selectColumn.getName()) && selectColumn.getTable().has_name()){
1044
//                    variablesToExclude.add(sel)
1045
//                }
1046
            }
1047

  
1048
        }, new ExpressionBuilder.VisitorFilter() {
1049
            @Override
1050
            public boolean skipChildren() {
1051
                return true;
1052
            }
1053
            
1054
            @Override
1055
            public boolean accept(ExpressionBuilder.Visitable visitable) {
1056
                if(select == visitable){
1057
                    return true;
1058
                }
1059
                if(visitable instanceof OrderByBuilder) {
1060
                    return false;
1061
                }
1062
                if(visitable instanceof SelectBuilder) {
1063
                    ArrayList<Column> columns = new ArrayList<>(parentColumns);
1064
                    for (SelectColumnBuilder column : select.getColumns()) {
1065
                        columns.add(sqlbuilder.column(
1066
                            table,
1067
                            column.getName()));
1068
                    }
1069
                    addTableToColumnReferencesInSingleSelect(sqlbuilder, (SelectBuilder) visitable, columns);
1070
                    return false;
1071
                }
1072
                return true;
1073
            }
1074
        });
1075
        
1076
        List<String> variableNamesToExclude = new ArrayList<>();
1077
        for(SQLBuilder.SelectColumnBuilder column : select.getColumns()){
1078
            if(StringUtils.isNotBlank(column.getAlias())){
1079
                variableNamesToExclude.add(column.getAlias());
1080
            } else {
1081
                parentColumns.add(sqlbuilder.column(
1082
                    table,
1083
                    column.getName()));
1084
            }
1085
        }
1086

  
1087
        for (ExpressionBuilder.Variable variable : variables) {
1088
            boolean found = false;
1089
            for (ExpressionBuilder.Value v : variablesToExclude) {
1090
                if(v == variable){
1091
                    found = true;
1092
                    break;
1093
                }
1094
            }
1095
            if(found){
1096
                continue;
1097
            }
1098
//            if(variableNamesToExclude.contains(variable.name())){
1099
//                continue;
1100
//            }
1101
            Column column = getColumn(parentColumns,variable.name());
1102
            if(column != null){
1103
                ExpressionBuilder.Variable variable_replacement = sqlbuilder.column(
1104
                        column.table(),
1105
                        variable.name()
1106
                );
1107
                value_replacements.add(
1108
                        new ExpressionBuilder.Value[]{
1109
                            variable,
1110
                            variable_replacement
1111
                        }
1112
                );
1113
            } else {
1114
                ExpressionBuilder.Variable variable_replacement = null;
1115
                if(variable instanceof SQLBuilder.Column){
1116
                    column = (SQLBuilder.Column) variable;
1117
                    if (column.table() == null || !column.table().has_name()) {
1118
                        variable_replacement = sqlbuilder.column(
1119
                                table,
1120
                                variable.name()
1121
                        );
1122
                    } else if(!column.table().has_schema()){
1123
                        SQLBuilder.TableNameBuilder t = sqlbuilder.table_name()
1124
                                .name(column.table().getName())
1125
                                .schema(table.getSchema()); //Mismo esquema que en el FROM
1126
                        variable_replacement = sqlbuilder.column(
1127
                                t,
1128
                                variable.name()
1129
                        );
1130
                    }
1131
                } else {
1132
                    variable_replacement = sqlbuilder.column(
1133
                            table,
1134
                            variable.name()
1135
                    );
1136
                }
1137
                if(variable_replacement != null){
1138
                    value_replacements.add(
1139
                            new ExpressionBuilder.Value[]{
1140
                                variable,
1141
                                variable_replacement
1142
                            }
1143
                    );
1144
                }
1145
            }
1146

  
1147
        }
1148

  
1149
        for (ExpressionBuilder.Value[] replaceValue : value_replacements) {
1150
            ExpressionBuilder.Value target = replaceValue[0];
1151
            ExpressionBuilder.Value replacement = replaceValue[1];
1152
            Boolean dontAddTableName = (Boolean) target.getProperty(DONT_ADD_TABLE_NAME_TO_COLUMNS);
1153
            if(dontAddTableName != null && dontAddTableName){
1154
                continue;
1155
            }
1156
            select.replace(target, replacement);
1157
        }
1158

  
1159
    }
1160
    
1161
    protected Column getColumn(List<Column> columns, String name){
1162
        for (int i = columns.size()-1; i >= 0; i--) {
1163
            if(StringUtils.equalsIgnoreCase(columns.get(i).name(), name)){
1164
                return columns.get(i);
1165
            }
1166
        }
1167
        return null;
1168
    }
1169

  
1170
    
983 1171
    @Override
984 1172
    public void setTransaction(DataTransactionServices transaction) {
985 1173
        this.transaction = transaction;
......
1003 1191
	public void expandCalculedColumns(JDBCSQLBuilderBase sqlbuilder) {
1004 1192
	    ComputedAttribute computedAttributeFormater = new ComputedAttribute(sqlbuilder, sqlbuilder.formatter());
1005 1193
            for (int i = 0; i < 10; i++) {
1006
                List<Pair<ExpressionBuilder.Value, ExpressionBuilder.Value>> variablesToReplace = new ArrayList<>();
1007
                sqlbuilder.accept(new ExpressionBuilder.Visitor() {
1008
                    @Override
1009
                    public void visit(ExpressionBuilder.Visitable value) {
1010
                        if (computedAttributeFormater.canApply((ExpressionBuilder.Value) value)) {
1011
                            ExpressionBuilder.Variable variable = (ExpressionBuilder.Variable) value;
1012
                            ExpressionBuilder.Value replace = computedAttributeFormater.expandedValue(variable);
1013
                            variablesToReplace.add(Pair.of(variable, replace));
1014
                        }
1194
                List<Pair<ExpressionBuilder.Variable, ExpressionBuilder.Value>> variablesToReplace = new ArrayList<>();
1195
                sqlbuilder.accept((ExpressionBuilder.Visitable value) -> {
1196
                    if (computedAttributeFormater.canApply((ExpressionBuilder.Value) value)) {
1197
                        ExpressionBuilder.Variable variable = (ExpressionBuilder.Variable) value;
1198
                        ExpressionBuilder.Value replace = computedAttributeFormater.expandedValue(variable);
1199
                        variablesToReplace.add(Pair.of(variable, replace));
1015 1200
                    }
1016 1201
                }, null);
1017 1202
                if (variablesToReplace.isEmpty()) {
1018 1203
                    break;
1019 1204
                } 
1020
                for (Pair<ExpressionBuilder.Value, ExpressionBuilder.Value> entry : variablesToReplace) {
1205
                for (Pair<ExpressionBuilder.Variable, ExpressionBuilder.Value> entry : variablesToReplace) {
1021 1206
                    ExpressionBuilder.Value variable = entry.getKey();
1022 1207
                    ExpressionBuilder.Value replace = entry.getValue();
1208
                    Boolean dontAddTableName = (Boolean) variable.getProperty(DONT_ADD_TABLE_NAME_TO_COLUMNS);
1209
                    if (dontAddTableName != null && dontAddTableName) {
1210
                        continue;
1211
                    }
1023 1212
                    sqlbuilder.select().replace(variable, replace);
1024 1213
                }
1025 1214
            }

Also available in: Unified diff