Statistics
| Revision:

svn-gvsig-desktop / 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 / operations / ResultSetForSetProviderOperation.java @ 46315

History | View | Annotate | Download (28.2 KB)

1
/**
2
 * gvSIG. Desktop Geographic Information System.
3
 *
4
 * Copyright (C) 2007-2020 gvSIG Association.
5
 *
6
 * This program is free software; you can redistribute it and/or
7
 * modify it under the terms of the GNU General Public License
8
 * as published by the Free Software Foundation; either version 3
9
 * of the License, or (at your option) any later version.
10
 *
11
 * This program is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 * GNU General Public License for more details.
15
 *
16
 * You should have received a copy of the GNU General Public License
17
 * along with this program; if not, write to the Free Software
18
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
19
 * MA  02110-1301, USA.
20
 *
21
 * For any additional information, do not hesitate to contact us
22
 * at info AT gvsig.com, or visit our website www.gvsig.com.
23
 */
24
package org.gvsig.fmap.dal.store.jdbc2.spi.operations;
25

    
26
import java.util.ArrayList;
27
import java.util.HashMap;
28
import java.util.List;
29
import java.util.Map;
30
import org.apache.commons.lang3.ArrayUtils;
31
import org.apache.commons.lang3.StringUtils;
32
import org.gvsig.expressionevaluator.Code;
33
import org.gvsig.expressionevaluator.Expression;
34
import org.gvsig.expressionevaluator.ExpressionBuilder;
35
import static org.gvsig.expressionevaluator.ExpressionBuilder.FUNCTION_LET;
36
import org.gvsig.expressionevaluator.ExpressionUtils;
37
import org.gvsig.fmap.dal.SQLBuilder.SelectBuilder;
38
import org.gvsig.fmap.dal.exception.DataException;
39
import org.gvsig.fmap.dal.expressionevaluator.FeatureAttributeEmulatorExpression;
40
import org.gvsig.fmap.dal.feature.EditableFeatureAttributeDescriptor;
41
import org.gvsig.fmap.dal.feature.FeatureAttributeDescriptor;
42
import org.gvsig.fmap.dal.feature.FeatureAttributeEmulator;
43
import org.gvsig.fmap.dal.feature.FeatureExtraColumns;
44
import org.gvsig.fmap.dal.feature.FeatureQuery;
45
import org.gvsig.fmap.dal.feature.FeatureQueryOrder;
46
import org.gvsig.fmap.dal.feature.FeatureQueryOrder.FeatureQueryOrderMember;
47
import org.gvsig.fmap.dal.feature.FeatureType;
48
import org.gvsig.fmap.dal.store.jdbc2.JDBCConnection;
49
import org.gvsig.fmap.dal.store.jdbc2.JDBCHelper;
50
import org.gvsig.fmap.dal.store.jdbc2.OperationsFactory.TableReference;
51
import org.gvsig.fmap.dal.store.jdbc2.ResulSetControler.ResultSetEntry;
52
import org.gvsig.fmap.dal.store.jdbc2.spi.JDBCSQLBuilderBase;
53
import static org.gvsig.fmap.dal.store.jdbc2.spi.JDBCSQLBuilderBase.PROP_FEATURE_TYPE;
54
import static org.gvsig.fmap.dal.store.jdbc2.spi.JDBCSQLBuilderBase.PROP_JDBCHELPER;
55
import static org.gvsig.fmap.dal.store.jdbc2.spi.JDBCSQLBuilderBase.PROP_QUERY;
56
import static org.gvsig.fmap.dal.store.jdbc2.spi.JDBCSQLBuilderBase.PROP_SYMBOLTABLE;
57
import static org.gvsig.fmap.dal.store.jdbc2.spi.JDBCSQLBuilderBase.PROP_TABLE;
58
import org.gvsig.fmap.geom.DataTypes;
59
import org.gvsig.tools.dynobject.DynField;
60
import org.gvsig.tools.evaluator.Evaluator;
61
import org.gvsig.tools.lang.CloneableUtils;
62

    
63
public class ResultSetForSetProviderOperation extends AbstractConnectionOperation {
64

    
65
    private final TableReference table;
66
    private final String baseFilter;
67
    private final String baseOrder;
68
    private final FeatureType storeType;
69
    private final FeatureType setType;
70
    private final FeatureQuery query;
71
    private final long limit;
72
    private final long offset;
73
    private final int fetchSize;
74

    
75
    public ResultSetForSetProviderOperation(
76
            JDBCHelper helper,
77
            TableReference table,
78
            String baseFilter,
79
            String baseOrder,
80
            FeatureQuery query,
81
            FeatureType storeType,
82
            FeatureType setType,
83
            long limit,
84
            long offset,
85
            int fetchSize
86
    ) {
87
        super(helper);
88
        this.table = table;
89
        this.baseFilter = baseFilter;
90
        this.baseOrder = baseOrder;
91
        this.storeType = storeType;
92
        this.setType = setType;
93
        this.query = query;
94
        this.limit = limit;
95
        this.offset = offset;
96
        this.fetchSize = fetchSize;
97
    }
98

    
99
    @Override
100
    protected Object perform_operation() throws Exception {
101
        ResultSetEntry rs = createResultSet();
102
        return rs;
103
    }
104

    
105
    @Override
106
    public Object perform(JDBCConnection conn) throws DataException {
107
        throw new UnsupportedOperationException("Not supported yet.");
108
    }
109

    
110
    public String getSQL() {
111
        List<FeatureAttributeDescriptor> columns = new ArrayList<>();
112
        JDBCSQLBuilderBase sqlbuilder = createSQLBuilder();
113
        String sql = this.getSQL(sqlbuilder, columns, null);
114
        return sql;
115
    }
116

    
117
    public String getSQL(
118
            JDBCSQLBuilderBase sqlbuilder,
119
            List<FeatureAttributeDescriptor> columns,
120
            List<String> extraColumnNames
121
    ) {
122
        double tolerance = -1; //query.getScale(); 
123
        ExpressionBuilder expbuilder = sqlbuilder.expression();
124
        SelectBuilder select = sqlbuilder.select();
125
        ArrayList<ExpressionBuilder.Value> valuesToRemoveFeatureType = new ArrayList<>();
126
        
127
        if( shouldUseACustomSelect() ) {
128
            String sql = table.getSubquery();
129
            if( StringUtils.containsAny(sql, "${where_filter}", "${and_filter}") ) {
130
                Evaluator filter = query.getFilter();
131
                if (filter != null) {
132
                    String sqlfilter = filter.getSQL();
133
                    if (!StringUtils.isEmpty(sqlfilter)) {
134
                        if (this.helper.supportFilter(this.storeType, filter)) {
135
                            select.where().set(expbuilder.toValue(sqlfilter));
136
                        }
137
                    }
138
                }
139
                if (!StringUtils.isEmpty(baseFilter)) {
140
                    select.where().and(expbuilder.toValue(baseFilter));
141
                }
142
            }
143
            if( StringUtils.containsAny(sql, "${order_by_orderspec}", "${comma_orderspec}") ) {
144
                FeatureQueryOrder order = query.getOrder();
145
                if (order != null) {
146
                    for (FeatureQueryOrderMember member : order.members()) {
147
                        String attrName = member.getAttributeName();
148
                        ExpressionBuilder.Variable col = expbuilder.column(attrName);
149
                        select.order_by().value(col).ascending(member.getAscending());
150
                    }
151
                }
152
            }
153
            if( select.has_where() || select.has_order_by() ) {
154
                sqlbuilder.setProperties(
155
                        null,
156
                        PROP_FEATURE_TYPE, this.storeType,
157
                        PROP_TABLE, table,
158
                        PROP_SYMBOLTABLE, this.query==null? null:this.query.getSymbolTable(),
159
                        PROP_JDBCHELPER, this.helper,
160
                        PROP_QUERY, this.query
161
                );
162
                for (ExpressionBuilder.Value value : valuesToRemoveFeatureType) {
163
                    value.setProperty(PROP_FEATURE_TYPE, null);
164
                }
165
                if( select.has_where()) {
166
                    String s = select.where().toString();
167
                    sql = StringUtils.replace(sql, "${where_filter}", "WHERE " + s);
168
                    sql = StringUtils.replace(sql, "${and_filter}", "AND (" + s + ")");
169
                }
170
                if( select.has_order_by() ) {
171
                    String s = select.order_by().toString();
172
                    sql = StringUtils.replace(sql, "${order_by_orderspec}", "ORDER BY " + s);
173
                    sql = StringUtils.replace(sql, "${comma_orderspec}", ", "+ s);
174
                }
175
            }
176
            for (FeatureAttributeDescriptor attr : storeType) {
177
                columns.add(attr);
178
            }
179
            return sql;
180
        }
181
        
182

    
183
        Map<String, EditableFeatureAttributeDescriptor> allExtraColumns = new HashMap<>();
184
        for (EditableFeatureAttributeDescriptor column : this.setType.getExtraColumns().getColumns()) {
185
            allExtraColumns.put(column.getName(), column);
186
        }
187
        if(query != null){
188
            for (EditableFeatureAttributeDescriptor column : this.query.getExtraColumn().getColumns()) {
189
                allExtraColumns.put(column.getName(), column);
190
            }
191
        }
192

    
193
        List<String> primaryKeys = new ArrayList<>();
194
        for (FeatureAttributeDescriptor attr : storeType.getPrimaryKey()) {
195
            primaryKeys.add(attr.getName());
196
        }
197
        List<String> forcedColumns = new ArrayList<>(primaryKeys);
198

    
199
        String[] constantsAttributeNames = null;
200
        if (query != null && query.hasConstantsAttributeNames()) {
201
            constantsAttributeNames = query.getConstantsAttributeNames();
202
        }
203
        for (FeatureAttributeDescriptor attr : setType) {
204
            if (attr.isComputed()) {
205
                // Campos calculados se a?aden despues para asegurarnos que
206
                // primeros se a?aden los campos reales y al final los calculados
207
                continue;
208
            }
209
            if (ArrayUtils.contains(constantsAttributeNames, attr.getName())) {
210
                continue;
211
            }
212
            if (attr.isPrimaryKey()) {
213
                forcedColumns.remove(attr.getName());
214
            }
215
            if (query != null && (query.hasGroupByColumns() || query.hasAggregateFunctions()) )  {
216
                String aggregate = query.getAggregate(this.table.getTable(), attr.getName());
217
                if (this.query.isAGroupByColumn(attr.getName())) {
218
                    select.column().name(attr.getName());
219
                } else if (aggregate == null) {
220
                    select.column().value(expbuilder.constant(null)).as(attr.getName());
221
                } else {
222
                    select.column()
223
                            .value(ExpressionUtils.compile(aggregate).toValue(expbuilder))
224
                            .as(attr.getName());
225
                }
226
            } else {
227
                if (attr.getType() == DataTypes.GEOMETRY) {
228
                    select.column().name(attr.getName()).as_geometry();
229
                    //                if( tolerance<=0 || !sqlbuilder.getConfig().has_functionality(Config.ST_Simplify)) {
230
                    //                    select.column().name(attr.getName()).as_geometry();
231
                    //                } else {
232
                    //                    select.column().value(
233
                    //                        sqlbuilder.ST_Simplify( 
234
                    //                            sqlbuilder.column(attr.getName()),
235
                    //                            sqlbuilder.constant(tolerance)
236
                    //                        )
237
                    //                    ).as_geometry();
238
                    //                }
239
                } else {
240
                    select.column().name(attr.getName());
241
                }
242
            }
243
            columns.add(attr);
244
        }
245

    
246
        if (query == null || !query.hasGroupByColumns()) {
247
            for (String attrName : forcedColumns) {
248
                select.column().name(attrName);
249
                FeatureAttributeDescriptor attr = setType.getAttributeDescriptor(attrName);
250
                // Ojo, que cuando estamos pintando una vista NO TENEMOS LA PK y attr vale null!!!!
251
                // No se si deberiamos forzar a que cuando se crea un subfeaturetype se meta siempre
252
                // la pk, o simplemente nunca asumir que la vamos a tener.
253
                if (attr != null) {
254
                    columns.add(attr);
255
                }
256
            }
257
        }
258
        
259
        // Despues de a?adir los campos reales, se a?aden los campos calculados
260
        for (FeatureAttributeDescriptor attr : setType) {
261
            if (attr.isComputed()) {
262
                if (attr.getRelationType() == DynField.RELATION_TYPE_NONE) {
263
                    FeatureAttributeEmulator attrEmulator = attr.getFeatureAttributeEmulator();
264
                    if (attrEmulator instanceof FeatureAttributeEmulatorExpression) {
265
                        FeatureAttributeEmulatorExpression x = (FeatureAttributeEmulatorExpression) attrEmulator;
266
                        Expression exp = x.getExpression();
267

    
268
                        if (query != null && query.hasGroupByColumns()) {
269
                            String aggregate = query.getAggregate(this.table.getTable(), attr.getName());
270
                            if (this.query.isAGroupByColumn(attr.getName())) {
271
                                if (!select.has_column(attr.getName())) {
272
                                    select.column().value(exp.getCode().toValue()).as(attr.getName());
273
                                }
274
                                if (extraColumnNames != null && !extraColumnNames.contains(attr.getName())) {
275
                                    extraColumnNames.add(attr.getName());
276
                                }
277
                            } else if (aggregate == null) {
278
                                select.column().value(expbuilder.constant(null)).as(attr.getName());
279
                                
280
                                if (extraColumnNames != null && !extraColumnNames.contains(attr.getName())) {
281
                                    extraColumnNames.add(attr.getName());
282
                                }
283
                            } else {
284
                                String fn = this.query.getAggregateFunctions().get(attr.getName());
285
                                ExpressionBuilder.Function aggregateExp = expbuilder.function(fn, exp.getCode().toValue());
286
                                if (!select.has_column(attr.getName())) {
287
                                    select.column().value(aggregateExp).as(attr.getName());
288
                                }
289
                                if (extraColumnNames != null && !extraColumnNames.contains(attr.getName())) {
290
                                    extraColumnNames.add(attr.getName());
291
                                }
292
                            }
293
                        } else {
294
                            if (exp != null && !exp.isEmpty() && this.helper.supportExpression(setType, exp.getPhrase())) {
295
                                Code code = exp.getCode();
296
                                select.column()
297
                                        .value(code.toValue(expbuilder))
298
                                        .as(attr.getName());
299
                                if (extraColumnNames != null && !extraColumnNames.contains(attr.getName())) {
300
                                    extraColumnNames.add(attr.getName());
301
                                }
302
                            }
303

    
304
                        }
305
                    }
306
                }
307
            }
308
        }
309
        
310
        if (query != null && (query.hasAggregateFunctions() ||  query.hasGroupByColumns())) { 
311
            // Hay que tener en cuenta que puede haber un MAX(CAMPO) sin que se especifique un GROUP BY
312
            if (query.hasAggregateFunctions() ) {
313
                for (Map.Entry<String, String> entry : query.getAggregateFunctions().entrySet()) {
314
                    Expression exp;
315
                    FeatureAttributeDescriptor attr = allExtraColumns.get(entry.getKey());
316
                    if (attr == null) {
317
                        attr = this.setType.getAttributeDescriptorFromAll(entry.getKey());
318
                    }
319
                    if (attr == null) {
320
                            exp = ExpressionUtils.createExpression(entry.getKey());
321
                            Code code = exp.getCode();
322
                            if (!(code instanceof Code.Callable)) {
323
                                throw new RuntimeException("Not able to use aggregate function with this expression(1): " + entry.getKey());
324
                            }
325
                            Code.Callable callable = (Code.Callable) code;
326
                            if (!callable.name().equalsIgnoreCase(FUNCTION_LET)) {
327
                                throw new RuntimeException("Not able to use aggregate function with this expression(2): " + entry.getKey());
328
                            }
329
                            String name = ((Code.Identifier) callable.parameters().get(0)).name();
330
                            ExpressionBuilder.Value aggregate = callable.parameters().get(1).toValue();
331

    
332
                            ExpressionBuilder.Function aggregateExp = expbuilder.function(entry.getValue(), aggregate);
333

    
334
                            select.remove_column(name);
335
                            select.column().value(aggregateExp).as(name);
336
                    } else if( attr.getFeatureAttributeEmulator()!=null ) {
337
                        exp = ((FeatureAttributeEmulatorExpression) attr.getFeatureAttributeEmulator()).getExpression();
338
                        ExpressionBuilder.Function aggregateExp = expbuilder.function(entry.getValue(), exp.getCode().toValue());
339
                        if (!select.has_column(attr.getName())) {
340
                            select.column().value(aggregateExp).as(attr.getName());
341
                        }
342
                        if (extraColumnNames != null && !extraColumnNames.contains(attr.getName())) {
343
                            extraColumnNames.add(attr.getName());
344
                        }
345
                    }
346
                }
347
            }
348
            if (query.hasGroupByColumns()) { // if tiene agrupacion
349
                for (String attrName : query.getGroupByColumns()) {
350
                    if (allExtraColumns.get(attrName) != null) { //from setType and query
351
                        EditableFeatureAttributeDescriptor attr = allExtraColumns.get(attrName);
352
                        ExpressionBuilder.Variable col = expbuilder.column(attrName);
353
                        select.group_by(col);
354
                        Expression exp = ((FeatureAttributeEmulatorExpression) attr.getFeatureAttributeEmulator()).getExpression();
355
                        if (!select.has_column(attrName)) {
356
                            select.column().value(exp.getCode().toValue()).as(attrName);
357
                        }
358
                        if (extraColumnNames!=null && !extraColumnNames.contains(attr.getName())) {
359
                            extraColumnNames.add(attrName);
360
                        }
361
                    } else if (setType.get(attrName) != null && setType.getAttributeDescriptor(attrName).isComputed()) {
362
                        FeatureAttributeDescriptor attr = setType.getAttributeDescriptor(attrName);
363
                        ExpressionBuilder.Variable col = expbuilder.column(attrName);
364
                        select.group_by(col);
365
                        Expression exp = ((FeatureAttributeEmulatorExpression) attr.getFeatureAttributeEmulator()).getExpression();
366
                        if (!select.has_column(attrName)) {
367
                            select.column().value(exp.getCode().toValue()).as(attrName);
368
                        }
369
                        if (extraColumnNames!=null && !extraColumnNames.contains(attr.getName())) {
370
                            extraColumnNames.add(attrName);
371
                        }
372
                    } else if (setType.get(attrName) == null) {
373
                        try {
374
                            Code code = ExpressionUtils.compile(attrName);
375
                            select.group_by(code.toValue());
376
                        } catch (Exception ex) {
377
                            throw new RuntimeException("Not able to create column by expression in groupby query", ex);
378
                        }
379
                    } else {
380
                        ExpressionBuilder.Function atrcolumn = expbuilder.getattr(this.table.getTable(), attrName);
381
                        select.group_by(atrcolumn);
382
                    }
383
                }
384
            }
385
        } else {
386
            if (this.query != null) {
387
                FeatureExtraColumns extraColumns = this.query.getExtraColumn();
388
                if (extraColumns != null && !extraColumns.isEmpty()) {
389
                    for (EditableFeatureAttributeDescriptor attr : extraColumns.getColumns()) {
390
                        if (!attr.isComputed()) {
391
                            continue;
392
                        }
393
                        FeatureAttributeEmulator attrEmulator = attr.getFeatureAttributeEmulator();
394
                        if (attrEmulator instanceof FeatureAttributeEmulatorExpression) {
395
                            FeatureAttributeEmulatorExpression x = (FeatureAttributeEmulatorExpression) attrEmulator;
396
                            Expression exp = x.getExpression();
397
                            if (exp != null && !exp.isEmpty() && this.helper.supportExpression(setType, exp.getPhrase())) {
398
                                Code code = exp.getCode();
399
                                select.column()
400
                                        .value(code.toValue(expbuilder))
401
                                        .as(attr.getName());
402
                                if (extraColumnNames!=null && !extraColumnNames.contains(attr.getName())) {
403
                                    extraColumnNames.add(attr.getName());
404
                                }
405
                            }
406
                        }
407
                    }
408
                }
409
            }
410
        }
411

    
412
        select.from().table()
413
                .database(this.table.getDatabase())
414
                .schema(this.table.getSchema())
415
                .name(this.table.getTable());
416
        select.from().subquery(this.table.getSubquery());
417

    
418
        Evaluator filter = query == null ? null : query.getFilter();
419
        if (filter != null) {
420
            String sqlfilter = filter.getSQL();
421
            if (!StringUtils.isEmpty(sqlfilter)) {
422
                if (this.helper.supportFilter(this.storeType, filter)) {
423
                    select.where().set(expbuilder.toValue(sqlfilter));
424
                }
425
            }
426
        }
427
        if (!StringUtils.isEmpty(baseFilter)) {
428
            select.where().and(expbuilder.toValue(baseFilter));
429
        }
430

    
431
        FeatureQueryOrder order = query == null ? null : query.getOrder();
432
        if (order != null) {
433
            for (FeatureQueryOrderMember member : order.members()) {
434
                String attrName = member.getAttributeName();
435
                if (member.hasEvaluator()) {
436
                    String sqlorder = member.getEvaluator().getSQL();
437
                    select.order_by()
438
                            .value(expbuilder.toValue(sqlorder))
439
                            .ascending(member.getAscending());
440
                } else {
441
                    if (allExtraColumns.get(attrName) != null) {
442
                        Expression exp = ((FeatureAttributeEmulatorExpression) allExtraColumns.get(attrName).getFeatureAttributeEmulator()).getExpression();
443
                        if (!select.has_column(attrName)) {
444
                            select.column().value(exp.getCode().toValue()).as(attrName);
445
                        }
446
                        if (extraColumnNames!=null && !extraColumnNames.contains(attrName)) {
447
                            extraColumnNames.add(attrName);
448
                        }
449
                    } else if (setType.get(attrName) != null && setType.getAttributeDescriptor(attrName).isComputed()) {
450
                        Expression exp = ((FeatureAttributeEmulatorExpression) setType.getAttributeDescriptor(attrName).getFeatureAttributeEmulator()).getExpression();
451
                        if (!select.has_column(attrName)) {
452
                            select.column().value(exp.getCode().toValue()).as(attrName);
453
                        }
454
                        if (extraColumnNames!=null && !extraColumnNames.contains(attrName)) {
455
                            extraColumnNames.add(attrName);
456
                        }
457
                    }
458
                    ExpressionBuilder.Variable col = expbuilder.column(attrName);
459
                                        
460
                    // En el groupBy no queremos que se sustituya el nombre del campo calculado
461
                    // por su expresion. Se encarga el formater y lo evitamos quitandole el ftype
462
                    // al value.
463
                    valuesToRemoveFeatureType.add(col);
464
                    select.order_by().value(col).ascending(member.getAscending());
465
//                    select.order_by()
466
//                            .column(member.getAttributeName())
467
//                            .ascending(member.getAscending());
468
                }
469
            }
470
        }
471

    
472
        if (!StringUtils.isEmpty(baseOrder)) {
473
            select.order_by().custom(baseOrder);
474
        }
475

    
476
        if (select.has_group_by()) { // && isPaginated()) {
477
            // Cuando paginamos debemos ordenar por las columnas del groupby.
478
            // Ordenamos siempre para obtener el mismo resultado cuando paginamos
479
            // y no paginamos.
480
            for (ExpressionBuilder.Value group : select.getGroups()) {
481
                if (select.getOrderBy(group) == null) {
482
                    ExpressionBuilder.Value v = (ExpressionBuilder.Value) CloneableUtils.cloneQuietly(group);
483
                    select.order_by().value(v).ascending();
484
                    valuesToRemoveFeatureType.add(v);
485
                }
486
            }
487
        }
488
        
489
        if (primaryKeys.isEmpty()) {
490
            // Muy probablemente si no tiene pk sea una vista, asi que 
491
            // pasaremos de ordenar y esperemos que la vista este ya ordenada.
492
            select.disable_check_order_and_offset();
493
        } else {
494
            // Siempre ordenamos por la clave primaria
495
            for (String attrName : primaryKeys) {
496
                if (select.getOrderBy(attrName) == null) {
497
                    select.order_by().column(attrName).ascending();
498
                }
499
            }
500
        }
501

    
502
        if (limit > 0) {
503
            select.limit(limit);
504
        } else {
505
            select.limit(query == null ? null : query.getLimit());
506
        }
507
        if (offset > 0) {
508
            select.offset(offset);
509
        }
510
        sqlbuilder.setProperties(
511
                null,
512
                PROP_FEATURE_TYPE, this.storeType,
513
                PROP_TABLE, table,
514
                PROP_SYMBOLTABLE, this.query==null? null:this.query.getSymbolTable(),
515
                PROP_JDBCHELPER, this.helper,
516
                PROP_QUERY, this.query
517
        );
518
        for (ExpressionBuilder.Value value : valuesToRemoveFeatureType) {
519
            value.setProperty(PROP_FEATURE_TYPE, null);
520
        }
521
        this.helper.expandCalculedColumns(sqlbuilder);
522
        this.helper.processSpecialFunctions(sqlbuilder, storeType, extraColumnNames);
523
        String sql = sqlbuilder.toString();
524
        return sql;
525
    }
526
    
527
    private boolean isPaginated() {
528
        // No tengo claro que (offset==0 && limit>0) sea lo mas correcto,
529
        // Pero cuando se va a paginar y se pide la primera pagina offset es
530
        // 0 y limit>0, y si no ordenamos ya esa primera pagina los resultados
531
        // que se obtienen no son correctos, ya que la primera pagina se saca
532
        // sin ordenar y el resto ordenadas.
533
        // Probablemente deberiamos tener alguna otra forma de detectar que
534
        // estamos paginanado ya que asi no distinguimo si solo queremos 
535
        // obtener los primeros elementos sin importarnos su orden.
536
        return (offset > 0 || (offset == 0 && limit > 0));
537
    }
538

    
539
    public ResultSetEntry createResultSet() throws DataException {
540
        List<FeatureAttributeDescriptor> columns = new ArrayList<>();
541
        List<String> extraColumnNames = new ArrayList<>();
542

    
543
        JDBCSQLBuilderBase sqlbuilder = createSQLBuilder();
544
        String sql = this.getSQL(sqlbuilder, columns, extraColumnNames);
545

    
546
        ResultSetEntry resultSetEntry = this.helper.getResulSetControler().create(
547
                sql, fetchSize,
548
                columns.toArray(new FeatureAttributeDescriptor[columns.size()]),
549
                extraColumnNames.toArray(new String[extraColumnNames.size()])
550
        );
551
        return resultSetEntry;
552
    }
553

    
554
    private boolean shouldUseACustomSelect() {
555
        if( !table.hasSubquery() ) {
556
            return false;
557
        }
558
        if( this.query == null ) {
559
            return false;
560
        }
561
        if( this.query.isUseSubquery() ) {
562
            return false;
563
        }
564
        if( this.query.hasGroupByColumns() ) {
565
            return false;
566
        }
567
        if( this.query.hasAggregateFunctions() ) {
568
            return false;
569
        }        
570
        if( !this.query.hasFilter() && !this.query.hasOrder() ) {
571
            return true;
572
        }
573
//        si el filtro es incompatible con la BBDD
574
//            return false
575
//        si el orden es incompatible con la BBDD
576
//            return false
577
//        si filtro u orden usan la funcion foreing_value 
578
//            return false;
579
        return true;
580
    }
581
}