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 @ 46163

History | View | Annotate | Download (27 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.sql.Connection;
27
import java.util.ArrayList;
28
import java.util.HashMap;
29
import java.util.List;
30
import java.util.Map;
31
import org.apache.commons.lang3.ArrayUtils;
32
import org.apache.commons.lang3.StringUtils;
33
import org.gvsig.expressionevaluator.Code;
34
import org.gvsig.expressionevaluator.Expression;
35
import org.gvsig.expressionevaluator.ExpressionBuilder;
36
import static org.gvsig.expressionevaluator.ExpressionBuilder.FUNCTION_LET;
37
import org.gvsig.expressionevaluator.ExpressionUtils;
38
import org.gvsig.fmap.dal.SQLBuilder.SelectBuilder;
39
import org.gvsig.fmap.dal.exception.DataException;
40
import org.gvsig.fmap.dal.expressionevaluator.FeatureAttributeEmulatorExpression;
41
import org.gvsig.fmap.dal.feature.EditableFeatureAttributeDescriptor;
42
import org.gvsig.fmap.dal.feature.FeatureAttributeDescriptor;
43
import org.gvsig.fmap.dal.feature.FeatureAttributeEmulator;
44
import org.gvsig.fmap.dal.feature.FeatureExtraColumns;
45
import org.gvsig.fmap.dal.feature.FeatureQuery;
46
import org.gvsig.fmap.dal.feature.FeatureQueryOrder;
47
import org.gvsig.fmap.dal.feature.FeatureQueryOrder.FeatureQueryOrderMember;
48
import org.gvsig.fmap.dal.feature.FeatureType;
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(Connection 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
//              if(StringUtils.isNotBlank(System.getenv("ENABLE_COMPUTED_SQL_ATTR"))) { 
206
                if (attr.getRelationType() == DynField.RELATION_TYPE_NONE) {
207
                    FeatureAttributeEmulator attrEmulator = attr.getFeatureAttributeEmulator();
208
                    if (attrEmulator instanceof FeatureAttributeEmulatorExpression) {
209
                        FeatureAttributeEmulatorExpression x = (FeatureAttributeEmulatorExpression) attrEmulator;
210
                        Expression exp = x.getExpression();
211

    
212
                        if (query != null && query.hasGroupByColumns()) {
213
                            String aggregate = query.getAggregate(this.table.getTable(), attr.getName());
214
                            if (this.query.isAGroupByColumn(attr.getName())) {
215
                                if (!select.has_column(attr.getName())) {
216
                                    select.column().value(exp.getCode().toValue()).as(attr.getName());
217
                                }
218
                                if (extraColumnNames != null && !extraColumnNames.contains(attr.getName())) {
219
                                    extraColumnNames.add(attr.getName());
220
                                }
221
                            } else if (aggregate == null) {
222
                                select.column().value(expbuilder.constant(null)).as(attr.getName());
223
                            } else {
224
                                String fn = this.query.getAggregateFunctions().get(attr.getName());
225
                                ExpressionBuilder.Function aggregateExp = expbuilder.function(fn, exp.getCode().toValue());
226
                                if (!select.has_column(attr.getName())) {
227
                                    select.column().value(aggregateExp).as(attr.getName());
228
                                }
229
                                if (extraColumnNames != null && !extraColumnNames.contains(attr.getName())) {
230
                                    extraColumnNames.add(attr.getName());
231
                                }
232
                            }
233
                        } else {
234
                            if (exp != null && !exp.isEmpty() && this.helper.supportExpression(setType, exp.getPhrase())) {
235
                                Code code = exp.getCode();
236
                                select.column()
237
                                        .value(code.toValue(expbuilder))
238
                                        .as(attr.getName());
239
                                if (extraColumnNames != null && !extraColumnNames.contains(attr.getName())) {
240
                                    extraColumnNames.add(attr.getName());
241
                                }
242
                            }
243

    
244
                        }
245
                    }
246
                }
247
//              }
248
                continue;
249
            }
250
            if (ArrayUtils.contains(constantsAttributeNames, attr.getName())) {
251
                continue;
252
            }
253
            if (attr.isPrimaryKey()) {
254
                forcedColumns.remove(attr.getName());
255
            }
256
            if (query != null && query.hasGroupByColumns()) {
257
                String aggregate = query.getAggregate(this.table.getTable(), attr.getName());
258
                if (this.query.isAGroupByColumn(attr.getName())) {
259
                    select.column().name(attr.getName());
260
                } else if (aggregate == null) {
261
                    select.column().value(expbuilder.constant(null)).as(attr.getName());
262
                } else {
263
                    select.column()
264
                            .value(ExpressionUtils.compile(aggregate).toValue(expbuilder))
265
                            .as(attr.getName());
266
                }
267
            } else {
268
                if (attr.getType() == DataTypes.GEOMETRY) {
269
                    select.column().name(attr.getName()).as_geometry();
270
                    //                if( tolerance<=0 || !sqlbuilder.getConfig().has_functionality(Config.ST_Simplify)) {
271
                    //                    select.column().name(attr.getName()).as_geometry();
272
                    //                } else {
273
                    //                    select.column().value(
274
                    //                        sqlbuilder.ST_Simplify( 
275
                    //                            sqlbuilder.column(attr.getName()),
276
                    //                            sqlbuilder.constant(tolerance)
277
                    //                        )
278
                    //                    ).as_geometry();
279
                    //                }
280
                } else {
281
                    select.column().name(attr.getName());
282
                }
283
            }
284
            columns.add(attr);
285
        }
286

    
287
        if (query != null && query.hasGroupByColumns()) {
288
            for (Map.Entry<String, String> entry : query.getAggregateFunctions().entrySet()) {
289
                Expression exp;
290
                FeatureAttributeDescriptor attr = allExtraColumns.get(entry.getKey());
291

    
292
                if (attr == null) {
293
                    attr = this.setType.getAttributeDescriptorFromAll(entry.getKey());
294

    
295
                    if (attr == null) {
296
                        exp = ExpressionUtils.createExpression(entry.getKey());
297
                        Code code = exp.getCode();
298
                        if (!(code instanceof Code.Callable)) {
299
                            throw new RuntimeException("Not able to use aggregate function with this expression(1): " + entry.getKey());
300
                        }
301
                        Code.Callable callable = (Code.Callable) code;
302
                        if (!callable.name().equalsIgnoreCase(FUNCTION_LET)) {
303
                            throw new RuntimeException("Not able to use aggregate function with this expression(2): " + entry.getKey());
304
                        }
305
                        String name = ((Code.Identifier) callable.parameters().get(0)).name();
306
                        ExpressionBuilder.Value aggregate = callable.parameters().get(1).toValue();
307

    
308
                        ExpressionBuilder.Function aggregateExp = expbuilder.function(entry.getValue(), aggregate);
309

    
310
                        select.remove_column(name);
311
                        select.column().value(aggregateExp).as(name);
312
                    }
313
                } else {
314
                    exp = ((FeatureAttributeEmulatorExpression) attr.getFeatureAttributeEmulator()).getExpression();
315
                    ExpressionBuilder.Function aggregateExp = expbuilder.function(entry.getValue(), exp.getCode().toValue());
316
                    if (!select.has_column(attr.getName())) {
317
                        select.column().value(aggregateExp).as(attr.getName());
318
                    }
319
                    if (extraColumnNames != null && !extraColumnNames.contains(attr.getName())) {
320
                        extraColumnNames.add(attr.getName());
321
                    }
322
                }
323
            }
324
            for (String attrName : query.getGroupByColumns()) {
325
                if (allExtraColumns.get(attrName) != null) { //from setType and query
326
                    EditableFeatureAttributeDescriptor attr = allExtraColumns.get(attrName);
327
                    ExpressionBuilder.Variable col = expbuilder.column(attrName);
328
                    select.group_by(col);
329
                    Expression exp = ((FeatureAttributeEmulatorExpression) attr.getFeatureAttributeEmulator()).getExpression();
330
                    if (!select.has_column(attrName)) {
331
                        select.column().value(exp.getCode().toValue()).as(attrName);
332
                    }
333
                    if (extraColumnNames!=null && !extraColumnNames.contains(attr.getName())) {
334
                        extraColumnNames.add(attrName);
335
                    }
336
                } else if (setType.get(attrName) != null && setType.getAttributeDescriptor(attrName).isComputed()) {
337
                    FeatureAttributeDescriptor attr = setType.getAttributeDescriptor(attrName);
338
                    ExpressionBuilder.Variable col = expbuilder.column(attrName);
339
                    select.group_by(col);
340
                    Expression exp = ((FeatureAttributeEmulatorExpression) attr.getFeatureAttributeEmulator()).getExpression();
341
                    if (!select.has_column(attrName)) {
342
                        select.column().value(exp.getCode().toValue()).as(attrName);
343
                    }
344
                    if (extraColumnNames!=null && !extraColumnNames.contains(attr.getName())) {
345
                        extraColumnNames.add(attrName);
346
                    }
347
                } else if (setType.get(attrName) == null) {
348
                    try {
349
                        Code code = ExpressionUtils.compile(attrName);
350
                        select.group_by(code.toValue());
351
                    } catch (Exception ex) {
352
                        throw new RuntimeException("Not able to create column by expression in groupby query", ex);
353
                    }
354
                } else {
355
                    ExpressionBuilder.Function atrcolumn = expbuilder.getattr(this.table.getTable(), attrName);
356
                    select.group_by(atrcolumn);
357
                }
358
            }
359
        } else {
360
            for (String attrName : forcedColumns) {
361
                select.column().name(attrName);
362
                FeatureAttributeDescriptor attr = setType.getAttributeDescriptor(attrName);
363
                // Ojo, que cuando estamos pintando una vista NO TENEMOS LA PK y attr vale null!!!!
364
                // No se si deberiamos forzar a que cuando se crea un subfeaturetype se meta siempre
365
                // la pk, o simplemente nunca asumir que la vamos a tener.
366
                if( attr!=null ) {
367
                    columns.add(attr);
368
                }
369
            }
370
            if (this.query != null) {
371
                FeatureExtraColumns extraColumns = this.query.getExtraColumn();
372
                if (extraColumns != null && !extraColumns.isEmpty()) {
373
                    for (EditableFeatureAttributeDescriptor attr : extraColumns.getColumns()) {
374
                        if (!attr.isComputed()) {
375
                            continue;
376
                        }
377
                        FeatureAttributeEmulator attrEmulator = attr.getFeatureAttributeEmulator();
378
                        if (attrEmulator instanceof FeatureAttributeEmulatorExpression) {
379
                            FeatureAttributeEmulatorExpression x = (FeatureAttributeEmulatorExpression) attrEmulator;
380
                            Expression exp = x.getExpression();
381
                            if (exp != null && !exp.isEmpty() && this.helper.supportExpression(setType, exp.getPhrase())) {
382
                                Code code = exp.getCode();
383
                                select.column()
384
                                        .value(code.toValue(expbuilder))
385
                                        .as(attr.getName());
386
                                if (extraColumnNames!=null && !extraColumnNames.contains(attr.getName())) {
387
                                    extraColumnNames.add(attr.getName());
388
                                }
389
                            }
390
                        }
391
                    }
392
                }
393
            }
394
        }
395

    
396
        select.from().table()
397
                .database(this.table.getDatabase())
398
                .schema(this.table.getSchema())
399
                .name(this.table.getTable());
400
        select.from().subquery(this.table.getSubquery());
401

    
402
        Evaluator filter = query == null ? null : query.getFilter();
403
        if (filter != null) {
404
            String sqlfilter = filter.getSQL();
405
            if (!StringUtils.isEmpty(sqlfilter)) {
406
                if (this.helper.supportFilter(this.storeType, filter)) {
407
                    select.where().set(expbuilder.toValue(sqlfilter));
408
                }
409
            }
410
        }
411
        if (!StringUtils.isEmpty(baseFilter)) {
412
            select.where().and(expbuilder.toValue(baseFilter));
413
        }
414

    
415
        FeatureQueryOrder order = query == null ? null : query.getOrder();
416
        if (order != null) {
417
            for (FeatureQueryOrderMember member : order.members()) {
418
                String attrName = member.getAttributeName();
419
                if (member.hasEvaluator()) {
420
                    String sqlorder = member.getEvaluator().getSQL();
421
                    select.order_by()
422
                            .value(expbuilder.toValue(sqlorder))
423
                            .ascending(member.getAscending());
424
                } else {
425
                    if (allExtraColumns.get(attrName) != null) {
426
                        Expression exp = ((FeatureAttributeEmulatorExpression) allExtraColumns.get(attrName).getFeatureAttributeEmulator()).getExpression();
427
                        if (!select.has_column(attrName)) {
428
                            select.column().value(exp.getCode().toValue()).as(attrName);
429
                        }
430
                        if (extraColumnNames!=null && !extraColumnNames.contains(attrName)) {
431
                            extraColumnNames.add(attrName);
432
                        }
433
                    } else if (setType.get(attrName) != null && setType.getAttributeDescriptor(attrName).isComputed()) {
434
                        Expression exp = ((FeatureAttributeEmulatorExpression) setType.getAttributeDescriptor(attrName).getFeatureAttributeEmulator()).getExpression();
435
                        if (!select.has_column(attrName)) {
436
                            select.column().value(exp.getCode().toValue()).as(attrName);
437
                        }
438
                        if (extraColumnNames!=null && !extraColumnNames.contains(attrName)) {
439
                            extraColumnNames.add(attrName);
440
                        }
441
                    }
442
                    ExpressionBuilder.Variable col = expbuilder.column(attrName);
443
                                        
444
                    // En el groupBy no queremos que se sustituya el nombre del campo calculado
445
                    // por su expresion. Se encarga el formater y lo evitamos quitandole el ftype
446
                    // al value.
447
                    valuesToRemoveFeatureType.add(col);
448
                    select.order_by().value(col).ascending(member.getAscending());
449
//                    select.order_by()
450
//                            .column(member.getAttributeName())
451
//                            .ascending(member.getAscending());
452
                }
453
            }
454
        }
455

    
456
        if (!StringUtils.isEmpty(baseOrder)) {
457
            select.order_by().custom(baseOrder);
458
        }
459

    
460
        if (select.has_group_by()) { // && isPaginated()) {
461
            // Cuando paginamos debemos ordenar por las columnas del groupby.
462
            // Ordenamos siempre para obtener el mismo resultado cuando paginamos
463
            // y no paginamos.
464
            for (ExpressionBuilder.Value group : select.getGroups()) {
465
                if (select.getOrderBy(group) == null) {
466
                    ExpressionBuilder.Value v = (ExpressionBuilder.Value) CloneableUtils.cloneQuietly(group);
467
                    select.order_by().value(v).ascending();
468
                    valuesToRemoveFeatureType.add(v);
469
                }
470
            }
471
        }
472
        
473
        if (primaryKeys.isEmpty()) {
474
            // Muy probablemente si no tiene pk sea una vista, asi que 
475
            // pasaremos de ordenar y esperemos que la vista este ya ordenada.
476
            select.disable_check_order_and_offset();
477
        } else {
478
            // Siempre ordenamos por la clave primaria
479
            for (String attrName : primaryKeys) {
480
                if (select.getOrderBy(attrName) == null) {
481
                    select.order_by().column(attrName).ascending();
482
                }
483
            }
484
        }
485

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

    
523
    public ResultSetEntry createResultSet() throws DataException {
524
        List<FeatureAttributeDescriptor> columns = new ArrayList<>();
525
        List<String> extraColumnNames = new ArrayList<>();
526

    
527
        JDBCSQLBuilderBase sqlbuilder = createSQLBuilder();
528
        String sql = this.getSQL(sqlbuilder, columns, extraColumnNames);
529

    
530
        ResultSetEntry resultSetEntry = this.helper.getResulSetControler().create(
531
                sql, fetchSize,
532
                columns.toArray(new FeatureAttributeDescriptor[columns.size()]),
533
                extraColumnNames.toArray(new String[extraColumnNames.size()])
534
        );
535
        return resultSetEntry;
536
    }
537

    
538
    private boolean shouldUseACustomSelect() {
539
        if( !table.hasSubquery() ) {
540
            return false;
541
        }
542
        if( this.query == null ) {
543
            return false;
544
        }
545
        if( this.query.isUseSubquery() ) {
546
            return false;
547
        }
548
        if( this.query.hasGroupByColumns() ) {
549
            return false;
550
        }
551
        if( this.query.hasAggregateFunctions() ) {
552
            return false;
553
        }        
554
        if( !this.query.hasFilter() && !this.query.hasOrder() ) {
555
            return true;
556
        }
557
//        si el filtro es incompatible con la BBDD
558
//            return false
559
//        si el orden es incompatible con la BBDD
560
//            return false
561
//        si filtro u orden usan la funcion foreing_value 
562
//            return false;
563
        return true;
564
    }
565
}