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 @ 47779
History | View | Annotate | Download (38.6 KB)
1 | 45065 | jjdelcerro | /**
|
---|---|---|---|
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 | 43020 | jjdelcerro | package org.gvsig.fmap.dal.store.jdbc2.spi.operations; |
25 | |||
26 | import java.util.ArrayList; |
||
27 | 45712 | omartinez | import java.util.HashMap; |
28 | 43020 | jjdelcerro | import java.util.List; |
29 | 45166 | omartinez | import java.util.Map; |
30 | 43358 | jjdelcerro | import org.apache.commons.lang3.ArrayUtils; |
31 | 43020 | jjdelcerro | import org.apache.commons.lang3.StringUtils; |
32 | 45155 | omartinez | import org.gvsig.expressionevaluator.Code; |
33 | 45162 | omartinez | import org.gvsig.expressionevaluator.Expression; |
34 | 44198 | jjdelcerro | import org.gvsig.expressionevaluator.ExpressionBuilder; |
35 | 46104 | omartinez | import static org.gvsig.expressionevaluator.ExpressionBuilder.FUNCTION_LET; |
36 | 46507 | jjdelcerro | import static org.gvsig.expressionevaluator.ExpressionBuilder.VALUE_NULL; |
37 | 46517 | fdiaz | import org.gvsig.expressionevaluator.ExpressionEvaluatorLocator; |
38 | 44727 | jjdelcerro | import org.gvsig.expressionevaluator.ExpressionUtils; |
39 | 46505 | fdiaz | import org.gvsig.expressionevaluator.GeometryExpressionBuilder; |
40 | 46517 | fdiaz | import org.gvsig.expressionevaluator.SymbolTable; |
41 | 46401 | jjdelcerro | import org.gvsig.fmap.dal.SQLBuilder; |
42 | 46505 | fdiaz | import org.gvsig.fmap.dal.SQLBuilder.Column; |
43 | 46401 | jjdelcerro | import org.gvsig.fmap.dal.SQLBuilder.OrderByBuilder; |
44 | 46518 | fdiaz | import static org.gvsig.fmap.dal.SQLBuilder.PROP_ADD_TABLE_NAME_TO_COLUMNS; |
45 | import static org.gvsig.fmap.dal.SQLBuilder.PROP_FEATURE_TYPE; |
||
46 | import static org.gvsig.fmap.dal.SQLBuilder.PROP_JDBCHELPER; |
||
47 | import static org.gvsig.fmap.dal.SQLBuilder.PROP_QUERY; |
||
48 | import static org.gvsig.fmap.dal.SQLBuilder.PROP_SYMBOLTABLE; |
||
49 | import static org.gvsig.fmap.dal.SQLBuilder.PROP_TABLE; |
||
50 | import static org.gvsig.fmap.dal.SQLBuilder.PROP_TABLENAME; |
||
51 | 44682 | jjdelcerro | import org.gvsig.fmap.dal.SQLBuilder.SelectBuilder; |
52 | 46518 | fdiaz | import org.gvsig.fmap.dal.SQLBuilder.TableNameBuilder; |
53 | 43020 | jjdelcerro | import org.gvsig.fmap.dal.exception.DataException; |
54 | 45162 | omartinez | import org.gvsig.fmap.dal.expressionevaluator.FeatureAttributeEmulatorExpression; |
55 | import org.gvsig.fmap.dal.feature.EditableFeatureAttributeDescriptor; |
||
56 | 43020 | jjdelcerro | import org.gvsig.fmap.dal.feature.FeatureAttributeDescriptor; |
57 | 45999 | omartinez | import org.gvsig.fmap.dal.feature.FeatureAttributeEmulator; |
58 | 43020 | jjdelcerro | import org.gvsig.fmap.dal.feature.FeatureQuery; |
59 | import org.gvsig.fmap.dal.feature.FeatureQueryOrder; |
||
60 | 43026 | jjdelcerro | import org.gvsig.fmap.dal.feature.FeatureQueryOrder.FeatureQueryOrderMember; |
61 | 43020 | jjdelcerro | import org.gvsig.fmap.dal.feature.FeatureType; |
62 | 46315 | jjdelcerro | import org.gvsig.fmap.dal.store.jdbc2.JDBCConnection; |
63 | 43020 | jjdelcerro | import org.gvsig.fmap.dal.store.jdbc2.JDBCHelper; |
64 | 46324 | jjdelcerro | import static org.gvsig.fmap.dal.store.jdbc2.JDBCServerExplorer.QUERY_DONT_ADD_PRIMARY_KEY_IN_THE_ORDER; |
65 | 44058 | jjdelcerro | import org.gvsig.fmap.dal.store.jdbc2.OperationsFactory.TableReference; |
66 | 43020 | jjdelcerro | import org.gvsig.fmap.dal.store.jdbc2.ResulSetControler.ResultSetEntry; |
67 | import org.gvsig.fmap.dal.store.jdbc2.spi.JDBCSQLBuilderBase; |
||
68 | import org.gvsig.fmap.geom.DataTypes; |
||
69 | 46324 | jjdelcerro | import org.gvsig.tools.dataTypes.DataTypeUtils; |
70 | 45999 | omartinez | import org.gvsig.tools.dynobject.DynField; |
71 | 43020 | jjdelcerro | import org.gvsig.tools.evaluator.Evaluator; |
72 | 46507 | jjdelcerro | import org.gvsig.tools.util.ChainedIterable; |
73 | 43020 | jjdelcerro | |
74 | public class ResultSetForSetProviderOperation extends AbstractConnectionOperation { |
||
75 | 45709 | omartinez | |
76 | 44058 | jjdelcerro | private final TableReference table; |
77 | 43020 | jjdelcerro | private final String baseFilter; |
78 | private final String baseOrder; |
||
79 | private final FeatureType storeType; |
||
80 | private final FeatureType setType; |
||
81 | private final FeatureQuery query; |
||
82 | private final long limit; |
||
83 | private final long offset; |
||
84 | private final int fetchSize; |
||
85 | |||
86 | public ResultSetForSetProviderOperation(
|
||
87 | JDBCHelper helper, |
||
88 | 44058 | jjdelcerro | TableReference table, |
89 | 43020 | jjdelcerro | String baseFilter,
|
90 | String baseOrder,
|
||
91 | FeatureQuery query, |
||
92 | FeatureType storeType, |
||
93 | FeatureType setType, |
||
94 | long limit,
|
||
95 | long offset,
|
||
96 | int fetchSize
|
||
97 | 45709 | omartinez | ) { |
98 | 43020 | jjdelcerro | super(helper);
|
99 | this.table = table;
|
||
100 | this.baseFilter = baseFilter;
|
||
101 | this.baseOrder = baseOrder;
|
||
102 | this.storeType = storeType;
|
||
103 | this.setType = setType;
|
||
104 | this.query = query;
|
||
105 | this.limit = limit;
|
||
106 | this.offset = offset;
|
||
107 | 45709 | omartinez | this.fetchSize = fetchSize;
|
108 | 43020 | jjdelcerro | } |
109 | |||
110 | @Override
|
||
111 | 43377 | jjdelcerro | protected Object perform_operation() throws Exception { |
112 | 44678 | jjdelcerro | ResultSetEntry rs = createResultSet(); |
113 | 43020 | jjdelcerro | return rs;
|
114 | } |
||
115 | 45709 | omartinez | |
116 | 43377 | jjdelcerro | @Override
|
117 | 46315 | jjdelcerro | public Object perform(JDBCConnection conn) throws DataException { |
118 | 45709 | omartinez | throw new UnsupportedOperationException("Not supported yet."); |
119 | 43377 | jjdelcerro | } |
120 | 44678 | jjdelcerro | |
121 | public String getSQL() { |
||
122 | 43358 | jjdelcerro | List<FeatureAttributeDescriptor> columns = new ArrayList<>(); |
123 | 43020 | jjdelcerro | JDBCSQLBuilderBase sqlbuilder = createSQLBuilder(); |
124 | 44682 | jjdelcerro | String sql = this.getSQL(sqlbuilder, columns, null); |
125 | 44678 | jjdelcerro | return sql;
|
126 | } |
||
127 | 45709 | omartinez | |
128 | 44682 | jjdelcerro | public String getSQL( |
129 | 45709 | omartinez | JDBCSQLBuilderBase sqlbuilder, |
130 | List<FeatureAttributeDescriptor> columns,
|
||
131 | 44682 | jjdelcerro | List<String> extraColumnNames |
132 | 45709 | omartinez | ) { |
133 | 46050 | omartinez | double tolerance = -1; //query.getScale(); |
134 | 44198 | jjdelcerro | ExpressionBuilder expbuilder = sqlbuilder.expression(); |
135 | 46517 | fdiaz | |
136 | expbuilder.setProperty(PROP_FEATURE_TYPE, this.storeType);
|
||
137 | expbuilder.setProperty(PROP_TABLE, table); |
||
138 | 46518 | fdiaz | expbuilder.setProperty(PROP_TABLENAME, table.getTable()); |
139 | 46517 | fdiaz | expbuilder.setProperty(PROP_SYMBOLTABLE, this.query==null? null:this.query.getSymbolTable()); |
140 | expbuilder.setProperty(PROP_JDBCHELPER, this.helper);
|
||
141 | expbuilder.setProperty(PROP_QUERY, this.query);
|
||
142 | |||
143 | 44682 | jjdelcerro | SelectBuilder select = sqlbuilder.select(); |
144 | 46505 | fdiaz | select.from().table() |
145 | .database(this.table.getDatabase())
|
||
146 | .schema(this.table.getSchema())
|
||
147 | .name(this.table.getTable());
|
||
148 | select.from().subquery(this.table.getSubquery());
|
||
149 | |||
150 | |||
151 | List<ExpressionBuilder.Value> valuesToRemoveFeatureType = new ArrayList<>(); |
||
152 | 46163 | jjdelcerro | |
153 | if( shouldUseACustomSelect() ) {
|
||
154 | 46505 | fdiaz | return processCustomSelect(select, expbuilder, sqlbuilder, valuesToRemoveFeatureType, columns);
|
155 | } |
||
156 | |||
157 | |||
158 | Map<String, EditableFeatureAttributeDescriptor> allExtraColumns = getAllExtraColumns(this.setType, this.query); |
||
159 | |||
160 | List<String> primaryKeys = new ArrayList<>(); |
||
161 | for (FeatureAttributeDescriptor attr : storeType.getPrimaryKey()) {
|
||
162 | primaryKeys.add(attr.getName()); |
||
163 | } |
||
164 | |||
165 | //Don't change order of this processes
|
||
166 | process1_SimpleFields(helper, setType, query, sqlbuilder, select, columns, primaryKeys, extraColumnNames); |
||
167 | process2_ComputedFields(helper, setType, query, sqlbuilder, select, extraColumnNames); |
||
168 | process3_Where(helper, storeType, query, sqlbuilder, select); |
||
169 | process4_Aggregates(this.table, this.setType, this.query, allExtraColumns, sqlbuilder, select, extraColumnNames); |
||
170 | process5_GroupBys(this.table, this.setType, this.query, allExtraColumns, sqlbuilder, select, extraColumnNames); |
||
171 | process6_OrderBy(storeType, setType, query, allExtraColumns, sqlbuilder, select, primaryKeys, extraColumnNames, valuesToRemoveFeatureType); |
||
172 | |||
173 | if (!StringUtils.isEmpty(baseFilter)) {
|
||
174 | select.where().and(expbuilder.toValue(baseFilter)); |
||
175 | } |
||
176 | |||
177 | if (!StringUtils.isEmpty(baseOrder)) {
|
||
178 | select.order_by().custom(baseOrder); |
||
179 | } |
||
180 | |||
181 | |||
182 | if (limit > 0) { |
||
183 | select.limit(limit); |
||
184 | } else {
|
||
185 | select.limit(query == null ? null : query.getLimit()); |
||
186 | } |
||
187 | if (offset > 0) { |
||
188 | select.offset(offset); |
||
189 | } |
||
190 | sqlbuilder.setProperties( |
||
191 | null,
|
||
192 | PROP_FEATURE_TYPE, this.storeType,
|
||
193 | PROP_TABLE, table, |
||
194 | PROP_SYMBOLTABLE, this.query==null? null:this.query.getSymbolTable(), |
||
195 | PROP_JDBCHELPER, this.helper,
|
||
196 | PROP_QUERY, this.query
|
||
197 | ); |
||
198 | for (ExpressionBuilder.Value value : valuesToRemoveFeatureType) {
|
||
199 | value.setProperty(PROP_FEATURE_TYPE, null);
|
||
200 | } |
||
201 | this.helper.expandCalculedColumns(sqlbuilder);
|
||
202 | this.helper.processSpecialFunctions(sqlbuilder, storeType, extraColumnNames);
|
||
203 | 46511 | jjdelcerro | String sql = StringUtils.trim(sqlbuilder.toString());
|
204 | 46505 | fdiaz | LOGGER.debug(sql); |
205 | return sql;
|
||
206 | } |
||
207 | |||
208 | private String processCustomSelect(SelectBuilder select, ExpressionBuilder expbuilder, JDBCSQLBuilderBase sqlbuilder, List<ExpressionBuilder.Value> valuesToRemoveFeatureType, List<FeatureAttributeDescriptor> columns) { |
||
209 | String sql = table.getSubquery();
|
||
210 | if( StringUtils.containsAny(sql, "${where_filter}", "${and_filter}") ) { |
||
211 | Evaluator filter = query.getFilter(); |
||
212 | if (filter != null) { |
||
213 | String sqlfilter = filter.getSQL();
|
||
214 | if (!StringUtils.isEmpty(sqlfilter)) {
|
||
215 | if (this.helper.supportFilter(this.storeType, filter)) { |
||
216 | select.where().set(expbuilder.toValue(sqlfilter)); |
||
217 | 46163 | jjdelcerro | } |
218 | } |
||
219 | } |
||
220 | 46505 | fdiaz | if (!StringUtils.isEmpty(baseFilter)) {
|
221 | select.where().and(expbuilder.toValue(baseFilter)); |
||
222 | 46163 | jjdelcerro | } |
223 | 46505 | fdiaz | } |
224 | if( StringUtils.containsAny(sql, "${order_by_orderspec}", "${comma_orderspec}") ) { |
||
225 | FeatureQueryOrder order = query.getOrder(); |
||
226 | if (order != null) { |
||
227 | for (FeatureQueryOrderMember member : order.members()) {
|
||
228 | String attrName = member.getAttributeName();
|
||
229 | ExpressionBuilder.Variable col = expbuilder.column(attrName); |
||
230 | select.order_by().value(col).ascending(member.getAscending()); |
||
231 | 46163 | jjdelcerro | } |
232 | } |
||
233 | 46505 | fdiaz | } |
234 | if( select.has_where() || select.has_order_by() ) {
|
||
235 | sqlbuilder.setProperties( |
||
236 | null,
|
||
237 | PROP_FEATURE_TYPE, this.storeType,
|
||
238 | PROP_TABLE, table, |
||
239 | PROP_SYMBOLTABLE, this.query==null? null:this.query.getSymbolTable(), |
||
240 | PROP_JDBCHELPER, this.helper,
|
||
241 | PROP_QUERY, this.query
|
||
242 | ); |
||
243 | for (ExpressionBuilder.Value value : valuesToRemoveFeatureType) {
|
||
244 | value.setProperty(PROP_FEATURE_TYPE, null);
|
||
245 | 46163 | jjdelcerro | } |
246 | 46505 | fdiaz | if( select.has_where()) {
|
247 | String s = select.where().toString();
|
||
248 | sql = StringUtils.replace(sql, "${where_filter}", "WHERE " + s); |
||
249 | sql = StringUtils.replace(sql, "${and_filter}", "AND (" + s + ")"); |
||
250 | } |
||
251 | if( select.has_order_by() ) {
|
||
252 | String s = select.order_by().toString();
|
||
253 | sql = StringUtils.replace(sql, "${order_by_orderspec}", "ORDER BY " + s); |
||
254 | sql = StringUtils.replace(sql, "${comma_orderspec}", ", "+ s); |
||
255 | } |
||
256 | 46163 | jjdelcerro | } |
257 | 46505 | fdiaz | for (FeatureAttributeDescriptor attr : storeType) {
|
258 | columns.add(attr); |
||
259 | 45712 | omartinez | } |
260 | 46505 | fdiaz | return sql;
|
261 | } |
||
262 | |||
263 | public static void process1_SimpleFields( |
||
264 | JDBCHelper helper, |
||
265 | FeatureType setType, |
||
266 | FeatureQuery query, |
||
267 | SQLBuilder sqlbuilder, |
||
268 | SelectBuilder select, |
||
269 | List<FeatureAttributeDescriptor> columns,
|
||
270 | List<String> primaryKeys, |
||
271 | List<String> extraColumnNames |
||
272 | ){ |
||
273 | if(!select.from().table().has_name()){
|
||
274 | throw new IllegalStateException("Need table in FROM."); |
||
275 | 45712 | omartinez | } |
276 | 46505 | fdiaz | |
277 | GeometryExpressionBuilder expbuilder = sqlbuilder.expression(); |
||
278 | |||
279 | 43706 | jjdelcerro | List<String> forcedColumns = new ArrayList<>(primaryKeys); |
280 | |||
281 | 43358 | jjdelcerro | String[] constantsAttributeNames = null; |
282 | 45709 | omartinez | if (query != null && query.hasConstantsAttributeNames()) { |
283 | 43358 | jjdelcerro | constantsAttributeNames = query.getConstantsAttributeNames(); |
284 | } |
||
285 | 46505 | fdiaz | |
286 | 45709 | omartinez | for (FeatureAttributeDescriptor attr : setType) {
|
287 | if (attr.isComputed()) {
|
||
288 | 46221 | omartinez | // Campos calculados se a?aden despues para asegurarnos que
|
289 | // primeros se a?aden los campos reales y al final los calculados
|
||
290 | continue;
|
||
291 | } |
||
292 | if (attr.isPrimaryKey()) {
|
||
293 | forcedColumns.remove(attr.getName()); |
||
294 | } |
||
295 | 46518 | fdiaz | if (ArrayUtils.contains(constantsAttributeNames, attr.getName()) && !attr.isPrimaryKey()) {
|
296 | select.column().name(attr.getName()).value(VALUE_NULL).as(attr.getName()); |
||
297 | } else if (attr.getType() == DataTypes.GEOMETRY) { |
||
298 | 46507 | jjdelcerro | select.column().name(attr.getName()).as_geometry(); |
299 | } else {
|
||
300 | select.column().name(attr.getName()); |
||
301 | } |
||
302 | 46221 | omartinez | columns.add(attr); |
303 | } |
||
304 | 46505 | fdiaz | |
305 | 46221 | omartinez | if (query == null || !query.hasGroupByColumns()) { |
306 | for (String attrName : forcedColumns) { |
||
307 | select.column().name(attrName); |
||
308 | FeatureAttributeDescriptor attr = setType.getAttributeDescriptor(attrName); |
||
309 | // Ojo, que cuando estamos pintando una vista NO TENEMOS LA PK y attr vale null!!!!
|
||
310 | // No se si deberiamos forzar a que cuando se crea un subfeaturetype se meta siempre
|
||
311 | // la pk, o simplemente nunca asumir que la vamos a tener.
|
||
312 | if (attr != null) { |
||
313 | columns.add(attr); |
||
314 | } |
||
315 | } |
||
316 | } |
||
317 | 46505 | fdiaz | } |
318 | |||
319 | public static void process2_ComputedFields(JDBCHelper helper, FeatureType setType, FeatureQuery query, SQLBuilder sqlbuilder, SelectBuilder select, List<String> extraColumnNames){ |
||
320 | if(!select.from().table().has_name()){
|
||
321 | throw new IllegalStateException("Need table in FROM."); |
||
322 | } |
||
323 | // En las columnas del select, si hay funciones de agregado en el select o un GROUP BY
|
||
324 | // los campos calculados que no lleven funci?n de agregado no deben incluir el nombre de tabla
|
||
325 | |||
326 | 46507 | jjdelcerro | for (FeatureAttributeDescriptor attr : attributeDescriptorsIterable(setType, query) ) {
|
327 | 46221 | omartinez | if (attr.isComputed()) {
|
328 | 47485 | fdiaz | FeatureAttributeEmulator attrEmulator = attr.getFeatureAttributeEmulator(); |
329 | if( !(attrEmulator instanceof FeatureAttributeEmulatorExpression) ) { |
||
330 | continue;
|
||
331 | } |
||
332 | FeatureAttributeEmulatorExpression x = (FeatureAttributeEmulatorExpression) attrEmulator; |
||
333 | Expression exp = x.getExpression();
|
||
334 | if (exp == null || exp.isEmpty() ) { |
||
335 | continue;
|
||
336 | } |
||
337 | if (!helper.supportExpression(null, exp.getPhrase())) { |
||
338 | continue;
|
||
339 | } |
||
340 | |||
341 | 46518 | fdiaz | ExpressionBuilder.Value value = createValueFromAttribute(sqlbuilder, attr, select.from().table()); |
342 | 46507 | jjdelcerro | if( value != VALUE_NULL ) {
|
343 | select.column() |
||
344 | .name(attr.getName()) |
||
345 | .value(value) |
||
346 | .as(attr.getName()); |
||
347 | if (extraColumnNames != null && !extraColumnNames.contains(attr.getName())) { |
||
348 | extraColumnNames.add(attr.getName()); |
||
349 | 46505 | fdiaz | } |
350 | 46507 | jjdelcerro | // if(query != null && (query.hasGroupByColumns() || query.hasAggregateFunctions())){
|
351 | addTableNameToColumns(sqlbuilder, value, true);
|
||
352 | // }
|
||
353 | 46505 | fdiaz | } |
354 | } |
||
355 | } |
||
356 | 46507 | jjdelcerro | |
357 | 46505 | fdiaz | } |
358 | 46104 | omartinez | |
359 | 46505 | fdiaz | public static void process4_Aggregates(TableReference table, FeatureType setType, FeatureQuery query, Map<String, EditableFeatureAttributeDescriptor> allExtraColumns, SQLBuilder sqlbuilder, SelectBuilder select, List<String> extraColumnNames) throws RuntimeException { |
360 | if(query == null){ |
||
361 | return;
|
||
362 | } |
||
363 | if(!select.from().table().has_name()){
|
||
364 | throw new IllegalStateException("Need table in FROM."); |
||
365 | } |
||
366 | GeometryExpressionBuilder expbuilder = sqlbuilder.expression(); |
||
367 | if (query.hasAggregateFunctions() ) {
|
||
368 | 46507 | jjdelcerro | // Ponemos NULL AS... en las columnas que no tengan funcion de argregado y no esten en el group by.
|
369 | for (FeatureAttributeDescriptor attr : attributeDescriptorsIterable(setType,query) ) {
|
||
370 | final String name = attr.getName(); |
||
371 | if( select.has_column(name) ) {
|
||
372 | // if( attr.isComputed() ) {
|
||
373 | // if (!query.isAggregate(name) ) {
|
||
374 | // select.column(name).value(VALUE_NULL).as(name);
|
||
375 | // }
|
||
376 | // } else {
|
||
377 | if ( !query.isAGroupByColumn(name) && !query.isAggregate(name) ) {
|
||
378 | select.column(name).value(VALUE_NULL).as(name); |
||
379 | } |
||
380 | // }
|
||
381 | 45709 | omartinez | } |
382 | 45166 | omartinez | } |
383 | 46505 | fdiaz | |
384 | for (Map.Entry<String, String> entry : query.getAggregateFunctions().entrySet()) { |
||
385 | 46507 | jjdelcerro | String aggregateFunction = entry.getValue();
|
386 | String aggregateExpression = entry.getKey();
|
||
387 | FeatureAttributeDescriptor attr = getAttributeDescriptor(aggregateExpression, setType, allExtraColumns); |
||
388 | 46505 | fdiaz | if (attr == null) { |
389 | //Aggregate_expression AS name -> name:=aggregate_expression
|
||
390 | 46507 | jjdelcerro | Expression exp = ExpressionUtils.createExpression(aggregateExpression);
|
391 | 46505 | fdiaz | Code code = exp.getCode(); |
392 | if (!(code instanceof Code.Callable)) { |
||
393 | 46507 | jjdelcerro | throw new RuntimeException("Not able to use aggregate function with this expression(1): " + aggregateExpression); |
394 | 46505 | fdiaz | } |
395 | Code.Callable callable = (Code.Callable) code; |
||
396 | if (!callable.name().equalsIgnoreCase(FUNCTION_LET)) {
|
||
397 | 46507 | jjdelcerro | throw new RuntimeException("Not able to use aggregate function with this expression(2): " + aggregateExpression); |
398 | 46505 | fdiaz | } |
399 | String name = ((Code.Identifier) callable.parameters().get(0)).name(); |
||
400 | 46507 | jjdelcerro | ExpressionBuilder.Value value = callable.parameters().get(1).toValue();
|
401 | 46505 | fdiaz | |
402 | 46507 | jjdelcerro | ExpressionBuilder.Function aggregateExp = expbuilder.function(aggregateFunction, value); |
403 | 46505 | fdiaz | select.column(name).value(aggregateExp).as(name); |
404 | } else {
|
||
405 | SQLBuilder.SelectColumnBuilder column = select.column(attr.getName()); |
||
406 | 46518 | fdiaz | ExpressionBuilder.Value value = createValueFromAttribute(sqlbuilder, attr, select.from().table()); |
407 | 46507 | jjdelcerro | ExpressionBuilder.Function aggregateExp = expbuilder.function(aggregateFunction, value); |
408 | addTableNameToColumns(sqlbuilder, aggregateExp, true);
|
||
409 | column.value(aggregateExp).as(attr.getName()); |
||
410 | 45155 | omartinez | } |
411 | 45709 | omartinez | } |
412 | 46505 | fdiaz | } |
413 | } |
||
414 | 46507 | jjdelcerro | |
415 | 46505 | fdiaz | public static void process5_GroupBys(TableReference table, FeatureType setType, FeatureQuery query, Map<String, EditableFeatureAttributeDescriptor> allExtraColumns, SQLBuilder sqlbuilder, SelectBuilder select, List<String> extraColumnNames) throws RuntimeException { |
416 | if(query == null){ |
||
417 | return;
|
||
418 | } |
||
419 | if(!select.from().table().has_name()){
|
||
420 | throw new IllegalStateException("Need table in FROM."); |
||
421 | } |
||
422 | if (query.hasGroupByColumns()) { // if tiene agrupacion |
||
423 | GeometryExpressionBuilder expbuilder = sqlbuilder.expression(); |
||
424 | 46507 | jjdelcerro | for (FeatureAttributeDescriptor attr : attributeDescriptorsIterable(setType,query.getExtraColumns()) ) {
|
425 | final String name = attr.getName(); |
||
426 | if( select.has_column(name) ) {
|
||
427 | // if( attr.isComputed() ) {
|
||
428 | // if (!query.isAggregate(name) ) {
|
||
429 | // select.column(name).value(VALUE_NULL).as(name);
|
||
430 | // }
|
||
431 | // } else {
|
||
432 | if ( !query.isAGroupByColumn(name) && !query.isAggregate(name) ) {
|
||
433 | select.column(name).value(VALUE_NULL).as(name); |
||
434 | } |
||
435 | // }
|
||
436 | 46505 | fdiaz | } |
437 | } |
||
438 | |||
439 | for (String attrName : query.getGroupByColumns()) { |
||
440 | 46507 | jjdelcerro | FeatureAttributeDescriptor attr = getAttributeDescriptor(attrName,setType, allExtraColumns); |
441 | if ( attr == null ) { |
||
442 | 46505 | fdiaz | try {
|
443 | Code code = ExpressionUtils.compile(attrName); |
||
444 | select.group_by(code.toValue()); |
||
445 | } catch (Exception ex) { |
||
446 | throw new RuntimeException("Not able to create column by expression in groupby query", ex); |
||
447 | 45999 | omartinez | } |
448 | 46505 | fdiaz | } else {
|
449 | 46518 | fdiaz | ExpressionBuilder.Value value = createValueFromAttribute(sqlbuilder, attr, select.from().table()); |
450 | 46507 | jjdelcerro | if( value instanceof Column ) { |
451 | 46518 | fdiaz | // ((Column)value).table(select.from().table());
|
452 | 46507 | jjdelcerro | if( select.getColumns().isEmpty() ) {
|
453 | // Tratamos de asegurarnos de que al menos hay una columna en el select
|
||
454 | select.column(attr.getName()); |
||
455 | } |
||
456 | } |
||
457 | addTableNameToColumns(sqlbuilder, value, true);
|
||
458 | select.group_by(value); |
||
459 | 45999 | omartinez | } |
460 | 46014 | jjdelcerro | } |
461 | 43020 | jjdelcerro | } |
462 | 46505 | fdiaz | } |
463 | |||
464 | public static void process3_Where( |
||
465 | JDBCHelper helper, |
||
466 | FeatureType storeType, |
||
467 | FeatureQuery query, |
||
468 | SQLBuilder sqlbuilder, |
||
469 | SelectBuilder select |
||
470 | ) { |
||
471 | if(query == null){ |
||
472 | return;
|
||
473 | } |
||
474 | if(!select.from().table().has_name()){
|
||
475 | throw new IllegalStateException("Need table in FROM."); |
||
476 | } |
||
477 | GeometryExpressionBuilder expbuilder = sqlbuilder.expression(); |
||
478 | |||
479 | Evaluator filter = query.getFilter(); |
||
480 | 45709 | omartinez | if (filter != null) { |
481 | 43020 | jjdelcerro | String sqlfilter = filter.getSQL();
|
482 | 45709 | omartinez | if (!StringUtils.isEmpty(sqlfilter)) {
|
483 | 46505 | fdiaz | if (helper.supportFilter(storeType, filter)) {
|
484 | 46507 | jjdelcerro | ExpressionBuilder.Value value = expbuilder.toValue(sqlfilter); |
485 | addTableNameToColumns(sqlbuilder, value, true);
|
||
486 | select.where().set(value); |
||
487 | 44198 | jjdelcerro | } |
488 | 43020 | jjdelcerro | } |
489 | } |
||
490 | 46505 | fdiaz | } |
491 | |||
492 | public static void process6_OrderBy( |
||
493 | FeatureType storeType, |
||
494 | FeatureType setType, |
||
495 | FeatureQuery query, |
||
496 | Map<String, EditableFeatureAttributeDescriptor> allExtraColumns, |
||
497 | SQLBuilder sqlbuilder, |
||
498 | SelectBuilder select, |
||
499 | List<String> primaryKeys, |
||
500 | List<String> extraColumnNames, |
||
501 | List<ExpressionBuilder.Value> valuesToRemoveFeatureType
|
||
502 | ) { |
||
503 | 46507 | jjdelcerro | //
|
504 | // https://learnsql.com/cookbook/how-to-order-rows-by-group-sum-in-sql/
|
||
505 | //
|
||
506 | |||
507 | 46505 | fdiaz | if(!select.from().table().has_name()){
|
508 | throw new IllegalStateException("Need table in FROM."); |
||
509 | 43020 | jjdelcerro | } |
510 | 46505 | fdiaz | GeometryExpressionBuilder expbuilder = sqlbuilder.expression(); |
511 | |||
512 | if (query != null) { |
||
513 | FeatureQueryOrder order = query.getOrder(); |
||
514 | if (order != null) { |
||
515 | 46507 | jjdelcerro | if (query.hasAggregateFunctions() || query.hasGroupByColumns()) {
|
516 | for (FeatureQueryOrderMember member : order.members()) {
|
||
517 | 46525 | fdiaz | if(member == null){ |
518 | continue;
|
||
519 | } |
||
520 | 46507 | jjdelcerro | String attrName = member.getAttributeName();
|
521 | FeatureAttributeDescriptor attr = getAttributeDescriptor(attrName, setType, allExtraColumns); |
||
522 | if( attr == null ) { |
||
523 | 46525 | fdiaz | if(member.getEvaluator() == null){ |
524 | select.order_by() |
||
525 | .column(attrName) |
||
526 | .ascending(member.getAscending()); |
||
527 | } else {
|
||
528 | // Order-by una expression en el query
|
||
529 | String sqlorder = member.getEvaluator().getSQL();
|
||
530 | select.order_by() |
||
531 | .value(expbuilder.toValue(sqlorder)) |
||
532 | .ascending(member.getAscending()); |
||
533 | } |
||
534 | 46507 | jjdelcerro | } else {
|
535 | ExpressionBuilder.Value value; |
||
536 | if ( query.isAGroupByColumn(attrName) ) {
|
||
537 | 46518 | fdiaz | value = createValueFromAttribute(sqlbuilder, attr, select.from().table()); |
538 | // if( value instanceof Column ) {
|
||
539 | // ((Column)value).table(select.from().table());
|
||
540 | // }
|
||
541 | 46507 | jjdelcerro | } else if ( query.isAggregate(attrName) ) { |
542 | String fn = query.getAggregateFunctions().get(attr.getName());
|
||
543 | 46518 | fdiaz | value = createValueFromAttribute(sqlbuilder, attr, select.from().table()); |
544 | // if( value instanceof Column ) {
|
||
545 | // ((Column)value).table(select.from().table());
|
||
546 | // }
|
||
547 | 46507 | jjdelcerro | value = expbuilder.function(fn, value); |
548 | } else {
|
||
549 | 46517 | fdiaz | continue;
|
550 | // throw new RuntimeException("Can't order by column '" + attrName + "', it does not have an aggregate function nor is it grouping by it.");
|
||
551 | 46505 | fdiaz | } |
552 | 46507 | jjdelcerro | int nullsMode = OrderByBuilder.MODE_NULLS_LAST;
|
553 | if ( !attr.allowNull() || attr.isPrimaryKey() ) {
|
||
554 | 46505 | fdiaz | // Puede ser costoso ordenar los nulos al principio o final, asi que
|
555 | // si el campo no admite nulos pasamos de indicarselo.
|
||
556 | nullsMode = OrderByBuilder.MODE_NULLS_NOT_SPECIFIED; |
||
557 | } |
||
558 | 46507 | jjdelcerro | |
559 | boolean expand;
|
||
560 | if ( !query.isAggregate(attrName) ) {
|
||
561 | if (select.has_aggregate_functions()) {
|
||
562 | expand = true;
|
||
563 | } else {
|
||
564 | expand = false;
|
||
565 | } |
||
566 | 46505 | fdiaz | } else {
|
567 | expand = false;
|
||
568 | } |
||
569 | 46507 | jjdelcerro | if (select.isGroupBy(attrName)) {
|
570 | expand = false;
|
||
571 | } |
||
572 | |||
573 | expandColumns(value, expand, valuesToRemoveFeatureType); |
||
574 | addTableNameToColumns(sqlbuilder, value, !attr.isComputed()); |
||
575 | select.order_by().value(value).ascending(member.getAscending()).nulls(nullsMode); |
||
576 | } |
||
577 | } |
||
578 | |||
579 | } else {
|
||
580 | for (FeatureQueryOrderMember member : order.members()) {
|
||
581 | 46525 | fdiaz | if(member == null){ |
582 | continue;
|
||
583 | } |
||
584 | 46507 | jjdelcerro | String attrName = member.getAttributeName();
|
585 | FeatureAttributeDescriptor attr = getAttributeDescriptor(attrName, setType, allExtraColumns); |
||
586 | if( attr == null ) { |
||
587 | 46525 | fdiaz | if(member.getEvaluator() == null){ |
588 | select.order_by() |
||
589 | .column(attrName) |
||
590 | .ascending(member.getAscending()); |
||
591 | } else {
|
||
592 | // Order-by una expression en el query
|
||
593 | String sqlorder = member.getEvaluator().getSQL();
|
||
594 | select.order_by() |
||
595 | .value(expbuilder.toValue(sqlorder)) |
||
596 | .ascending(member.getAscending()); |
||
597 | } |
||
598 | 46505 | fdiaz | } else {
|
599 | 46507 | jjdelcerro | Column column = sqlbuilder.column(attr.getName()); |
600 | if( !attr.isComputed() ) {
|
||
601 | column.table(select.from().table()); |
||
602 | } |
||
603 | int nullsMode = OrderByBuilder.MODE_NULLS_LAST;
|
||
604 | if ( !attr.allowNull() || attr.isPrimaryKey() ) {
|
||
605 | // Puede ser costoso ordenar los nulos al principio o final, asi que
|
||
606 | // si el campo no admite nulos pasamos de indicarselo.
|
||
607 | nullsMode = OrderByBuilder.MODE_NULLS_NOT_SPECIFIED; |
||
608 | } |
||
609 | expandColumns(column, false, valuesToRemoveFeatureType);
|
||
610 | addTableNameToColumns(sqlbuilder, column, !attr.isComputed()); |
||
611 | select.order_by().value(column).ascending(member.getAscending()).nulls(nullsMode); |
||
612 | 45712 | omartinez | } |
613 | 43020 | jjdelcerro | } |
614 | } |
||
615 | } |
||
616 | } |
||
617 | 46507 | jjdelcerro | if( query!=null && !query.hasOrder() ) { |
618 | 46505 | fdiaz | // Si no hay orden y hay grupos ordenaremos por estos
|
619 | 46507 | jjdelcerro | if( query.hasGroupByColumns() ) { // && isPaginated()) { |
620 | 46505 | fdiaz | // Cuando paginamos debemos ordenar por las columnas del groupby.
|
621 | // Ordenamos siempre para obtener el mismo resultado cuando paginamos
|
||
622 | // y no paginamos.
|
||
623 | 46507 | jjdelcerro | for (String attrName : query.getGroupByColumns()) { |
624 | FeatureAttributeDescriptor attr = getAttributeDescriptor(attrName,setType, allExtraColumns); |
||
625 | if ( attr != null ) { |
||
626 | if( query.getOrder().get(attrName)==null ) { |
||
627 | ExpressionBuilder.Value value; |
||
628 | 46518 | fdiaz | value = createValueFromAttribute(sqlbuilder, attr, select.from().table()); |
629 | // if( value instanceof Column ) {
|
||
630 | // ((Column)value).table(select.from().table());
|
||
631 | // }
|
||
632 | 46507 | jjdelcerro | int nullsMode = OrderByBuilder.MODE_NULLS_LAST;
|
633 | if ( !attr.allowNull() || attr.isPrimaryKey() ) {
|
||
634 | // Puede ser costoso ordenar los nulos al principio o final, asi que
|
||
635 | // si el campo no admite nulos pasamos de indicarselo.
|
||
636 | nullsMode = OrderByBuilder.MODE_NULLS_NOT_SPECIFIED; |
||
637 | } |
||
638 | expandColumns(value, true, valuesToRemoveFeatureType);
|
||
639 | addTableNameToColumns(sqlbuilder, value, true);
|
||
640 | select.order_by().value(value).ascending(true).nulls(nullsMode);
|
||
641 | 46505 | fdiaz | } |
642 | } |
||
643 | 45709 | omartinez | } |
644 | } |
||
645 | 46105 | omartinez | } |
646 | 46505 | fdiaz | |
647 | 46105 | omartinez | if (primaryKeys.isEmpty()) {
|
648 | // Muy probablemente si no tiene pk sea una vista, asi que
|
||
649 | // pasaremos de ordenar y esperemos que la vista este ya ordenada.
|
||
650 | select.disable_check_order_and_offset(); |
||
651 | } else {
|
||
652 | 46505 | fdiaz | if (query == null || !(query.hasAggregateFunctions() || query.hasGroupByColumns())) { |
653 | 46465 | fdiaz | // Siempre ordenamos por la clave primaria
|
654 | 46505 | fdiaz | Object x = query == null ? null : query.getQueryParameter(QUERY_DONT_ADD_PRIMARY_KEY_IN_THE_ORDER); |
655 | if (x == null || !DataTypeUtils.toBoolean(x)) { |
||
656 | 46465 | fdiaz | for (String attrName : primaryKeys) { |
657 | if (select.getOrderBy(attrName) == null) { |
||
658 | 46505 | fdiaz | ExpressionBuilder.Variable col = sqlbuilder.column(select.from().table(),attrName); |
659 | 46465 | fdiaz | select.order_by() |
660 | 46505 | fdiaz | .value(col) //column(attrName)
|
661 | 46465 | fdiaz | .ascending() |
662 | .nulls(OrderByBuilder.MODE_NULLS_NOT_SPECIFIED) |
||
663 | ; |
||
664 | // No tengo claro que pasa si se esta agrupando, y no se ha
|
||
665 | // incluido en el agrupamiento al PK. En ese caso el select
|
||
666 | // que se genera tendria una pinta tal que asi:
|
||
667 | // SELECT NULL as pk, ... ORDER BY pk ASC
|
||
668 | // Probablemente en ese caso no tendriamos que meter la PK
|
||
669 | // en el order-by ya que creo que no cambiaria el resultado.
|
||
670 | } |
||
671 | 46324 | jjdelcerro | } |
672 | 46105 | omartinez | } |
673 | 45989 | fdiaz | } |
674 | } |
||
675 | 46105 | omartinez | |
676 | 44678 | jjdelcerro | } |
677 | 46507 | jjdelcerro | |
678 | 46105 | omartinez | private boolean isPaginated() { |
679 | // No tengo claro que (offset==0 && limit>0) sea lo mas correcto,
|
||
680 | // Pero cuando se va a paginar y se pide la primera pagina offset es
|
||
681 | // 0 y limit>0, y si no ordenamos ya esa primera pagina los resultados
|
||
682 | // que se obtienen no son correctos, ya que la primera pagina se saca
|
||
683 | // sin ordenar y el resto ordenadas.
|
||
684 | // Probablemente deberiamos tener alguna otra forma de detectar que
|
||
685 | // estamos paginanado ya que asi no distinguimo si solo queremos
|
||
686 | // obtener los primeros elementos sin importarnos su orden.
|
||
687 | return (offset > 0 || (offset == 0 && limit > 0)); |
||
688 | } |
||
689 | 45709 | omartinez | |
690 | 44678 | jjdelcerro | public ResultSetEntry createResultSet() throws DataException { |
691 | List<FeatureAttributeDescriptor> columns = new ArrayList<>(); |
||
692 | 44682 | jjdelcerro | List<String> extraColumnNames = new ArrayList<>(); |
693 | |||
694 | 44678 | jjdelcerro | JDBCSQLBuilderBase sqlbuilder = createSQLBuilder(); |
695 | 44682 | jjdelcerro | String sql = this.getSQL(sqlbuilder, columns, extraColumnNames); |
696 | 45709 | omartinez | |
697 | 43020 | jjdelcerro | ResultSetEntry resultSetEntry = this.helper.getResulSetControler().create(
|
698 | 45709 | omartinez | sql, fetchSize, |
699 | 44376 | jjdelcerro | columns.toArray(new FeatureAttributeDescriptor[columns.size()]),
|
700 | 44682 | jjdelcerro | extraColumnNames.toArray(new String[extraColumnNames.size()]) |
701 | 43020 | jjdelcerro | ); |
702 | return resultSetEntry;
|
||
703 | } |
||
704 | 45709 | omartinez | |
705 | 46163 | jjdelcerro | private boolean shouldUseACustomSelect() { |
706 | if( !table.hasSubquery() ) {
|
||
707 | return false; |
||
708 | } |
||
709 | if( this.query == null ) { |
||
710 | return false; |
||
711 | } |
||
712 | if( this.query.isUseSubquery() ) { |
||
713 | return false; |
||
714 | } |
||
715 | if( this.query.hasGroupByColumns() ) { |
||
716 | return false; |
||
717 | } |
||
718 | if( this.query.hasAggregateFunctions() ) { |
||
719 | return false; |
||
720 | } |
||
721 | if( !this.query.hasFilter() && !this.query.hasOrder() ) { |
||
722 | return true; |
||
723 | } |
||
724 | // si el filtro es incompatible con la BBDD
|
||
725 | // return false
|
||
726 | // si el orden es incompatible con la BBDD
|
||
727 | // return false
|
||
728 | // si filtro u orden usan la funcion foreing_value
|
||
729 | // return false;
|
||
730 | return true; |
||
731 | } |
||
732 | 46507 | jjdelcerro | |
733 | public static Map<String, EditableFeatureAttributeDescriptor> getAllExtraColumns(FeatureType setType, FeatureQuery query) { |
||
734 | Map<String, EditableFeatureAttributeDescriptor> allExtraColumns = new HashMap<>(); |
||
735 | for (EditableFeatureAttributeDescriptor column : setType.getExtraColumns().getColumns()) {
|
||
736 | allExtraColumns.put(column.getName(), column); |
||
737 | } |
||
738 | if(query != null){ |
||
739 | for (EditableFeatureAttributeDescriptor column : query.getExtraColumn().getColumns()) {
|
||
740 | allExtraColumns.put(column.getName(), column); |
||
741 | } |
||
742 | } |
||
743 | return allExtraColumns;
|
||
744 | } |
||
745 | |||
746 | private static Iterable<FeatureAttributeDescriptor> attributeDescriptorsIterable(Iterable... iterables) { |
||
747 | return new ChainedIterable<>(iterables); |
||
748 | } |
||
749 | |||
750 | private static Iterable<FeatureAttributeDescriptor> attributeDescriptorsIterable(FeatureType setType, FeatureQuery query) { |
||
751 | if( query == null ) { |
||
752 | return new ChainedIterable<>(setType); |
||
753 | } |
||
754 | return attributeDescriptorsIterable(setType, query.getExtraColumns());
|
||
755 | } |
||
756 | |||
757 | private static boolean existsAttributeDescriptor(String attrName, FeatureType setType, Map<String, EditableFeatureAttributeDescriptor> allExtraColumns) { |
||
758 | return getAttributeDescriptor(attrName, setType, allExtraColumns)!=null; |
||
759 | } |
||
760 | |||
761 | private static FeatureAttributeDescriptor getAttributeDescriptor(String attrName, FeatureType setType, Map<String, EditableFeatureAttributeDescriptor> extraColumns) { |
||
762 | FeatureAttributeDescriptor attr = null;
|
||
763 | if( setType!=null ) { |
||
764 | attr = setType.getAttributeDescriptorFromAll(attrName); |
||
765 | } |
||
766 | if(attr == null && extraColumns!=null){ |
||
767 | attr = extraColumns.get(attrName); |
||
768 | } |
||
769 | return attr;
|
||
770 | } |
||
771 | |||
772 | private static void expandColumns(ExpressionBuilder.Value value, boolean expand, List<ExpressionBuilder.Value> valuesToRemoveFeatureType) { |
||
773 | if(!expand){
|
||
774 | // En el OrderBy no queremos que se sustituya el nombre del campo calculado
|
||
775 | // por su expresion. Se encarga el formater y lo evitamos quitandole el ftype
|
||
776 | // al value.
|
||
777 | valuesToRemoveFeatureType.add(value); |
||
778 | } |
||
779 | } |
||
780 | private static void addTableNameToColumns(SQLBuilder sqlbuilder, ExpressionBuilder.Value expression, boolean add) { |
||
781 | 46518 | fdiaz | sqlbuilder.setProperties(expression, null, PROP_ADD_TABLE_NAME_TO_COLUMNS, add);
|
782 | 46507 | jjdelcerro | } |
783 | |||
784 | |||
785 | 46518 | fdiaz | private static ExpressionBuilder.Value createValueFromAttribute(SQLBuilder sqlbuilder, FeatureAttributeDescriptor attr, TableNameBuilder tableBuilder) { |
786 | 46517 | fdiaz | switch(attr.getRelationType()) {
|
787 | case DynField.RELATION_TYPE_AGGREGATE:
|
||
788 | case DynField.RELATION_TYPE_COMPOSITION:
|
||
789 | return VALUE_NULL;
|
||
790 | case DynField.RELATION_TYPE_NONE:
|
||
791 | case DynField.RELATION_TYPE_IDENTITY:
|
||
792 | case DynField.RELATION_TYPE_COLLABORATION:
|
||
793 | break;
|
||
794 | 46507 | jjdelcerro | } |
795 | 46517 | fdiaz | |
796 | 46507 | jjdelcerro | if( attr.isComputed() ) {
|
797 | FeatureAttributeEmulator attrEmulator = attr.getFeatureAttributeEmulator(); |
||
798 | if( !(attrEmulator instanceof FeatureAttributeEmulatorExpression) ) { |
||
799 | return VALUE_NULL;
|
||
800 | } |
||
801 | FeatureAttributeEmulatorExpression x = (FeatureAttributeEmulatorExpression) attrEmulator; |
||
802 | Expression exp = x.getExpression();
|
||
803 | if (exp == null || exp.isEmpty() ) { |
||
804 | return VALUE_NULL;
|
||
805 | } |
||
806 | Code code = exp.getCode(); |
||
807 | 46517 | fdiaz | |
808 | SymbolTable symbolTable = ExpressionEvaluatorLocator.getExpressionEvaluatorManager().getInmutableSymbolTable(); |
||
809 | |||
810 | code.link(symbolTable); |
||
811 | 46507 | jjdelcerro | ExpressionBuilder.Value value = code.toValue(sqlbuilder.expression()); |
812 | return value;
|
||
813 | } |
||
814 | // Es un campo de la tabla
|
||
815 | 46518 | fdiaz | Column column = sqlbuilder.column(tableBuilder, attr.getName()); |
816 | 46507 | jjdelcerro | return column;
|
817 | } |
||
818 | |||
819 | 43020 | jjdelcerro | } |