Statistics
| Revision:

svn-gvsig-desktop / trunk / org.gvsig.desktop / org.gvsig.desktop.compat.cdc / org.gvsig.fmap.dal / org.gvsig.fmap.dal.impl / src / test / java / org / gvsig / expressionevaluator / TestGrammarCompiler.java @ 47735

History | View | Annotate | Download (34.8 KB)

1
package org.gvsig.expressionevaluator;
2

    
3
import java.util.Objects;
4
import javax.json.JsonObject;
5
import junit.framework.TestCase;
6
import static org.gvsig.fmap.dal.SQLBuilder.PROP_SQLBUILDER;
7
import org.gvsig.fmap.dal.feature.spi.SQLBuilderBase;
8
import org.gvsig.json.Json;
9
import org.gvsig.tools.library.impl.DefaultLibrariesInitializer;
10
import org.slf4j.Logger;
11
import org.slf4j.LoggerFactory;
12

    
13
/**
14
 *
15
 * @author jjdelcerro
16
 */
17
public class TestGrammarCompiler extends TestCase {
18

    
19
    private static Logger LOGGER = LoggerFactory.getLogger(TestGrammarCompiler.class);
20
    
21
    public TestGrammarCompiler(String testName) {
22
        super(testName);
23
    }
24

    
25
    @Override
26
    protected void setUp() throws Exception {
27
        super.setUp();
28
        new DefaultLibrariesInitializer().fullInitialize();
29
    }
30

    
31
    @Override
32
    protected void tearDown() throws Exception {
33
        super.tearDown();
34
    }
35

    
36
    // TODO add test methods here. The name must begin with 'test'. For example:
37
    // public void testHello() {}
38
    
39
    protected LexicalAnalyzer createLexicalAnalyzer() {
40
        ExpressionEvaluatorManager manager = ExpressionEvaluatorLocator.getManager();
41
        LexicalAnalyzer lexer = manager.createLexicalAnalyzer();
42
        return lexer;
43
    }
44

    
45
    protected org.gvsig.expressionevaluator.Compiler createCompiler() {
46
        ExpressionEvaluatorManager manager = ExpressionEvaluatorLocator.getManager();
47
        Compiler compiler = manager.createCompiler();
48
        compiler.setLexicalAnalyzer(createLexicalAnalyzer());
49
        return compiler;
50
    }
51

    
52
    protected SymbolTable createSymbolTable() {
53
        ExpressionEvaluatorManager manager = ExpressionEvaluatorLocator.getManager();
54
        MutableSymbolTable symbolTable = manager.createSymbolTable();
55
        symbolTable.setVar("precio", 200);
56
        symbolTable.setVar("1990", 0.168873933773767);
57
        return symbolTable;
58
    }
59

    
60
    protected Interpreter createInterpreter(SymbolTable symbolTable) {
61
        ExpressionEvaluatorManager manager = ExpressionEvaluatorLocator.getManager();
62
        Interpreter interpreter = manager.createInterpreter();
63
        interpreter.setSymbolTable(symbolTable);
64
        return interpreter;
65
    }
66
    
67
    private void link(Code code) {
68
      code.link(createSymbolTable());
69
    }
70

    
71
    private void dump(String testname, Object expected, Object actual) {
72
        System.out.println("### ---------------------");
73
        System.out.println("### "+testname);
74
        System.out.println("### expected: ["+Objects.toString(expected)+"]");
75
        System.out.println("### actual  : ["+Objects.toString(actual)+"]");
76
    }
77
    
78
    private void checkEquals(String testname, Object expected, Object actual) {
79
        dump(testname,expected,actual);
80
        assertEquals(expected, actual);
81
    }
82

    
83
    private void checkEquals(Object expected, Object actual) {
84
        try {
85
            throw new RuntimeException();
86
        } catch(Throwable t) {
87
            String testname = t.getStackTrace()[1].getMethodName();
88
            dump(testname,expected,actual);
89
            assertEquals(expected, actual);
90
        }
91
    }
92

    
93
    private String replaceExists(String s) {
94
        String s2 = s.replaceAll("'EXISTS[a-zA-Z0-9]*'", "'EXISTS0123456789abcdef'");
95
        return s2;
96
    }
97

    
98
    private String replaceExists(Code code) {
99
        return replaceExists(code.toString());
100
    }
101

    
102
    public void testSelect() {
103
        StringBuilder source = new StringBuilder();
104
        source.append("SELECT * FROM countries");
105

    
106
        Compiler compiler = createCompiler();
107

    
108
        Code code = compiler.compileExpression(source.toString());
109
        checkEquals("testSelect", "SELECT(TUPLE(), \"countries\", NULL, TUPLE(), TUPLE(), NULL)", code.toString());
110
        link(code);
111
        checkEquals("testSelect", "( SELECT * FROM \"countries\" )", code.toString());
112
    }
113
    
114
    public void testSelect1() {
115
        StringBuilder source = new StringBuilder();
116
        source.append("SELECT * FROM countries;");
117

    
118
        Compiler compiler = createCompiler();
119
        compiler.addCompatibility("SELECT","OPTIONAL_SEMICOLON_AT_END");
120

    
121
        Code code = compiler.compileExpression(source.toString());
122
        checkEquals("testSelect1", "SELECT(TUPLE(), \"countries\", NULL, TUPLE(), TUPLE(), NULL)", code.toString());
123
        link(code);
124
        checkEquals("testSelect1", "( SELECT * FROM \"countries\" )", code.toString());
125
    }
126
    
127
    public void testSelectInExpression1() {
128
        StringBuilder source = new StringBuilder();
129
        source.append("{ \"phrase\" : \"SELECT * FROM countries;\" }");
130
        
131
        JsonObject exp_json = Json.createObject(source.toString());
132
        Expression exp = ExpressionUtils.createExpressionFromJson(exp_json);
133
        
134
        checkEquals("( SELECT * FROM \"countries\" )", exp.getPhrase());
135

    
136
    }
137
    
138
    public void testSelectInExpression2() {
139
        StringBuilder source = new StringBuilder();
140
        source.append("\n" +
141
                "{\n" +
142
                "    \"__classname__\":\"org.gvsig.expressionevaluator.impl.DefaultExpression\",\n" +
143
                "    \"phrase\":\"SELECT * FROM countries;\",\n" +
144
                "    \"version\":\"2.6.0-1\"\n" +
145
                "}");
146
        
147
        JsonObject exp_json = Json.createObject(source.toString());
148
        Expression exp = ExpressionUtils.createExpressionFromJson(exp_json);
149
        
150
        // Esta comprobaci?n es para asegurarnos de que en la versi?n "2.6.0-1" no elimina el ";" aunque la sentencia sea incorrecta
151
        checkEquals("SELECT * FROM countries;", exp.getPhrase());
152
    }
153
    
154
    public void testSelectInExpression3() {
155
        StringBuilder source = new StringBuilder();
156
        source.append("\n" +
157
                "{\n" +
158
                "    \"__classname__\":\"org.gvsig.expressionevaluator.impl.DefaultExpression\",\n" +
159
                "    \"phrase\":\"SELECT * FROM countries\",\n" +
160
                "    \"version\":\"2.6.0-1\"\n" +
161
                "}");
162
        
163
        JsonObject exp_json = Json.createObject(source.toString());
164
        Expression exp = ExpressionUtils.createExpressionFromJson(exp_json);
165
        
166
        // Esta comprobaci?n es para asegurarnos de que en la versi?n "2.6.0-1" no la toca
167
        checkEquals("SELECT * FROM countries", exp.getPhrase());
168
    }
169
    
170
    public void testSelectToValue() {
171
        StringBuilder source = new StringBuilder();
172
        source.append("SELECT * FROM countries");
173

    
174
        Compiler compiler = createCompiler();
175

    
176
        Code code = compiler.compileExpression(source.toString());
177
        link(code);
178

    
179
        ExpressionBuilder builder = ExpressionUtils.createExpressionBuilder();
180
        builder.setProperty(PROP_SQLBUILDER, new SQLBuilderBase());
181
        checkEquals("testSelectToValue", "( SELECT * FROM \"countries\" )", code.toValue(builder).toString());
182
    }
183
    
184
    public void testSelectCount() {
185
        StringBuilder source = new StringBuilder();
186
        source.append("SELECT COUNT(*) FROM countries");
187

    
188
        Compiler compiler = createCompiler();
189

    
190
        Code code = compiler.compileExpression(source.toString());
191
        link(code);
192
        checkEquals("testSelectCount", "( SELECT COUNT(*) FROM \"countries\" )", code.toString());
193
    }
194
    
195
    public void testSelectAggregate() {
196
        StringBuilder source = new StringBuilder();
197
        source.append("SELECT SUM(\"TOTAL_MUERTOS\") FROM \"ARENA2_ACCIDENTES\"");
198

    
199
        Compiler compiler = createCompiler();
200

    
201
        Code code = compiler.compileExpression(source.toString());
202
        link(code);
203
        checkEquals("testSelectAggregate", "( SELECT SUM(\"TOTAL_MUERTOS\") FROM \"ARENA2_ACCIDENTES\" )", code.toString());
204
    }
205
    
206
    public void testSelectCountToValue() {
207
        StringBuilder source = new StringBuilder();
208
        source.append("SELECT COUNT(*) FROM countries");
209

    
210
        Compiler compiler = createCompiler();
211

    
212
        Code code = compiler.compileExpression(source.toString());
213
        link(code);
214

    
215
        ExpressionBuilder builder = ExpressionUtils.createExpressionBuilder();
216
        builder.setProperty(PROP_SQLBUILDER, new SQLBuilderBase());
217
        checkEquals("testSelectCountToValue", "( SELECT COUNT(*) FROM \"countries\" )", code.toValue(builder).toString());
218
    }
219
    
220
    public void testSelect2() {
221
        StringBuilder source = new StringBuilder();
222
        source.append("BEGIN ");
223
        source.append("  SET X = 0; ");
224
        source.append("  FOR row in SELECT * FROM countries "); // Con ;
225
        source.append("    LOOP ");
226
        source.append("      IF row.LASTCENSUS > 0 THEN ");
227
        source.append("        SET X = X + row.LASTCENSUS ");
228
        source.append("      END IF ");
229
        source.append("    END LOOP ");
230
        source.append("END");
231

    
232
        Compiler compiler = createCompiler();
233

    
234
        Code code = compiler.compileExpression(source.toString());
235
        link(code);
236
        checkEquals("testSelect2", "BEGIN \"X\" := 0; FOR \"row\" IN ( SELECT * FROM \"countries\" ) LOOP IF (\"row\".\"LASTCENSUS\" > 0) THEN \"X\" := (\"X\" + \"row\".\"LASTCENSUS\"); END IF END LOOP; END ", code.toString());
237
    }
238

    
239
    public void testSelect3() {
240
        StringBuilder source = new StringBuilder();
241
        source.append("BEGIN ");
242
        source.append("  SET X = 0; ");
243
        source.append("  FOR row in (SELECT * FROM countries) "); // Con parentesis
244
        source.append("    LOOP ");
245
        source.append("      IF row.LASTCENSUS > 0 THEN ");
246
        source.append("        SET X = X + row.LASTCENSUS ");
247
        source.append("      END IF ");
248
        source.append("    END LOOP ");
249
        source.append("END");
250

    
251
        Compiler compiler = createCompiler();
252

    
253
        Code code = compiler.compileExpression(source.toString());
254
        link(code);
255
        checkEquals("testSelect3", "BEGIN \"X\" := 0; FOR \"row\" IN ( SELECT * FROM \"countries\" ) LOOP IF (\"row\".\"LASTCENSUS\" > 0) THEN \"X\" := (\"X\" + \"row\".\"LASTCENSUS\"); END IF END LOOP; END ", code.toString());
256
    }
257

    
258
        public void testSelect4() {
259
        StringBuilder source = new StringBuilder();
260
        source.append("BEGIN ");
261
        source.append("  SET X = 0; ");
262
        source.append("  FOR row in SELECT * FROM countries "); 
263
        source.append("    LOOP ");
264
        source.append("      IF row.LASTCENSUS > 0 THEN ");
265
        source.append("        SET X = X + row.LASTCENSUS ");
266
        source.append("      END IF ");
267
        source.append("    END LOOP ");
268
        source.append("END");
269

    
270
        Compiler compiler = createCompiler();
271

    
272
        Code code = compiler.compileExpression(source.toString());
273
        link(code);
274
        checkEquals("testSelect4", "BEGIN \"X\" := 0; FOR \"row\" IN ( SELECT * FROM \"countries\" ) LOOP IF (\"row\".\"LASTCENSUS\" > 0) THEN \"X\" := (\"X\" + \"row\".\"LASTCENSUS\"); END IF END LOOP; END ", code.toString());
275
    }
276

    
277
    public void testSelect5() {
278
        StringBuilder source = new StringBuilder();
279
        source.append("BEGIN ");
280
        source.append("  SELECT * INTO ROW FROM countries ;"); 
281
        source.append("  ROW; ");
282
        source.append("END");
283

    
284
        Compiler compiler = createCompiler();
285

    
286
        Code code = compiler.compileExpression(source.toString());
287
        link(code);
288
        checkEquals("testSelect5", "BEGIN ( SELECT * INTO ROW FROM \"countries\" ); \"ROW\"; END ", code.toString());
289
    }
290

    
291
    public void testSelect5b() {
292
        StringBuilder source = new StringBuilder();
293
        source.append("BEGIN ");
294
        source.append("  X := 10; ");
295
        source.append("  SELECT * FROM countries ORDER BY (LASTCENSUS + X);"); 
296
        source.append("END");
297

    
298
        Compiler compiler = createCompiler();
299

    
300
        Code code = compiler.compileExpression(source.toString());
301
        link(code);
302
        checkEquals("testSelect5", "BEGIN \"X\" := 10; ( SELECT * FROM \"countries\" ORDER BY (\"LASTCENSUS\" + \"X\") ASC NULLS LAST ); END ", code.toString());
303
    }
304
    
305
    public void testSelect6() {
306
        StringBuilder source = new StringBuilder();
307
        source.append("BEGIN ");
308
        source.append("  ROWS := (SELECT * FROM countries );"); 
309
        source.append("  ROWS; ");
310
        source.append("END");
311

    
312
        Compiler compiler = createCompiler();
313

    
314
        Code code = compiler.compileExpression(source.toString());
315
        link(code);
316
        checkEquals("testSelect6", "BEGIN \"ROWS\" := ( SELECT * FROM \"countries\" ); \"ROWS\"; END ", code.toString());
317
    }
318

    
319
    public void testSelectWhere() {
320
        StringBuilder source = new StringBuilder();
321
        source.append("SELECT * FROM countries  ");
322
        source.append("  WHERE LASTCENSUS > 0");
323

    
324
        Compiler compiler = createCompiler();
325

    
326
        Code code = compiler.compileExpression(source.toString());
327
        link(code);
328
        checkEquals("testSelectWhere", "( SELECT * FROM \"countries\" WHERE (\"LASTCENSUS\" > 0) )", code.toString());
329
    }
330

    
331
    public void testSelectCountWhere() {
332
        StringBuilder source = new StringBuilder();
333
        source.append("SELECT COUNT(*) FROM countries  ");
334
        source.append("  WHERE LASTCENSUS > 0");
335

    
336
        Compiler compiler = createCompiler();
337

    
338
        Code code = compiler.compileExpression(source.toString());
339
        link(code);
340
        checkEquals("testSelectCountWhere", "( SELECT COUNT(*) FROM \"countries\" WHERE (\"LASTCENSUS\" > 0) )", code.toString());
341
    }
342

    
343
    public void testSelectCountWhere2() {
344
        StringBuilder source = new StringBuilder();
345
        source.append("BEGIN");
346
        source.append("  tableName := 'countries';");
347
        source.append("  SELECT COUNT(*) FROM :(tableName)  ");
348
        source.append("    WHERE countries.LASTCENSUS > 0 ; ");
349
        source.append("END");
350

    
351
        Compiler compiler = createCompiler();
352

    
353
        Code code = compiler.compileExpression(source.toString());
354
        link(code);
355
        checkEquals("testSelectCountWhere2", "BEGIN \"tableName\" := 'countries'; ( SELECT COUNT(*) FROM :(\"tableName\") WHERE (\"countries\".\"LASTCENSUS\" > 0) ); END ", code.toString());
356
    }
357

    
358
    public void testSelectWhere2() {
359
        StringBuilder source = new StringBuilder();
360
        source.append("SELECT * FROM countries  ");
361
        source.append("  WHERE countries.LASTCENSUS > 0");
362

    
363
        Compiler compiler = createCompiler();
364

    
365
        Code code = compiler.compileExpression(source.toString());
366
        link(code);
367
        checkEquals("testSelectWhere2", "( SELECT * FROM \"countries\" WHERE (\"countries\".\"LASTCENSUS\" > 0) )", code.toString());
368
    }
369

    
370
    public void testSelectWhere3() {
371
        StringBuilder source = new StringBuilder();
372
        source.append("BEGIN");
373
        source.append("  tableName := 'countries';");
374
        source.append("  SELECT * FROM :tableName  ");
375
        source.append("    WHERE countries.LASTCENSUS > 0 ; ");
376
        source.append("END");
377

    
378
        Compiler compiler = createCompiler();
379

    
380
        Code code = compiler.compileExpression(source.toString());
381
        link(code);
382
        checkEquals("testSelectWhere3", "BEGIN \"tableName\" := 'countries'; ( SELECT * FROM :(\"tableName\") WHERE (\"countries\".\"LASTCENSUS\" > 0) ); END ", code.toString());
383
    }
384

    
385
    public void testSelectWhereToValue3() {
386
        StringBuilder source = new StringBuilder();
387
        source.append("BEGIN");
388
        source.append("  SELECT * FROM countries  ");
389
        source.append("    WHERE countries.LASTCENSUS > 0 ; ");
390
        source.append("END");
391

    
392
        Compiler compiler = createCompiler();
393

    
394
        Code code = compiler.compileExpression(source.toString());
395
        link(code);
396
        checkEquals("testSelectWhereToValue3", "BEGIN ( SELECT * FROM \"countries\" WHERE (\"countries\".\"LASTCENSUS\" > 0) ); END ", code.toString());
397
        ExpressionBuilder builder = ExpressionUtils.createExpressionBuilder();
398
        builder.setProperty(PROP_SQLBUILDER, new SQLBuilderBase());
399
        checkEquals("testSelectWhereToValue3", "BLOCK(( SELECT * FROM \"countries\" WHERE (\"countries\".\"LASTCENSUS\" > 0) ))", code.toValue(builder).toString());
400
    }
401

    
402
    public void testSelectCountWhereToValue3() {
403
        StringBuilder source = new StringBuilder();
404
        source.append("BEGIN");
405
        source.append("  SELECT COUNT(*) FROM countries  ");
406
        source.append("    WHERE countries.LASTCENSUS > 0 ; ");
407
        source.append("END");
408

    
409
        Compiler compiler = createCompiler();
410

    
411
        Code code = compiler.compileExpression(source.toString());
412
        link(code);
413
        checkEquals("testSelectCountWhereToValue3", "BEGIN ( SELECT COUNT(*) FROM \"countries\" WHERE (\"countries\".\"LASTCENSUS\" > 0) ); END ", code.toString());
414
        ExpressionBuilder builder = ExpressionUtils.createExpressionBuilder();
415
        builder.setProperty(PROP_SQLBUILDER, new SQLBuilderBase());
416
        checkEquals("testSelectCountWhereToValue3", "BLOCK(( SELECT COUNT(*) FROM \"countries\" WHERE (\"countries\".\"LASTCENSUS\" > 0) ))", code.toValue(builder).toString());
417
    }
418

    
419
    public void testSelectOrder() {
420
        StringBuilder source = new StringBuilder();
421
        source.append("SELECT * FROM countries  ");
422
        source.append("  ORDER BY CONTINENT ASC, LASTCENSUS DESC");
423

    
424
        Compiler compiler = createCompiler();
425

    
426
        Code code = compiler.compileExpression(source.toString());
427
        link(code);
428
        checkEquals("testSelectOrder", "( SELECT * FROM \"countries\" ORDER BY \"CONTINENT\" ASC NULLS LAST, \"LASTCENSUS\" DESC NULLS LAST )", code.toString());
429
    }
430

    
431
    public void testSelectWhereOrder() {
432
        StringBuilder source = new StringBuilder();
433
        source.append("SELECT * FROM countries  ");
434
        source.append("  WHERE LASTCENSUS > 0  ");
435
        source.append("  ORDER BY ID");
436

    
437
        Compiler compiler = createCompiler();
438

    
439
        Code code = compiler.compileExpression(source.toString());
440
        link(code);
441
        checkEquals("testSelectWhereOrder", "( SELECT * FROM \"countries\" WHERE (\"LASTCENSUS\" > 0) ORDER BY \"ID\" ASC NULLS LAST )", code.toString());
442
    }
443

    
444
    public void testSelectWhereOrderNullsLast() {
445
        StringBuilder source = new StringBuilder();
446
        source.append("SELECT * FROM countries  ");
447
        source.append("  WHERE LASTCENSUS > 0  ");
448
        source.append("  ORDER BY ID NULLS LAST");
449

    
450
        Compiler compiler = createCompiler();
451

    
452
        Code code = compiler.compileExpression(source.toString());
453
        link(code);
454
        checkEquals("testSelectWhereOrder", "( SELECT * FROM \"countries\" WHERE (\"LASTCENSUS\" > 0) ORDER BY \"ID\" ASC NULLS LAST )", code.toString());
455
    }
456

    
457
    public void testSelectWhereOrderNullsFirst() {
458
        StringBuilder source = new StringBuilder();
459
        source.append("SELECT * FROM countries  ");
460
        source.append("  WHERE LASTCENSUS > 0  ");
461
        source.append("  ORDER BY ID NULLS FIRST");
462

    
463
        Compiler compiler = createCompiler();
464

    
465
        Code code = compiler.compileExpression(source.toString());
466
        link(code);
467
        checkEquals("testSelectWhereOrder", "( SELECT * FROM \"countries\" WHERE (\"LASTCENSUS\" > 0) ORDER BY \"ID\" ASC NULLS LAST )", code.toString());
468
    }
469

    
470
    public void testSelectWhereOrderLimit() {
471
        StringBuilder source = new StringBuilder();
472
        source.append("SELECT * FROM countries  ");
473
        source.append("  WHERE LASTCENSUS > 0  ");
474
        source.append("  ORDER BY LASTCENSUS DESC");
475
        source.append("  LIMIT 3");
476

    
477
        Compiler compiler = createCompiler();
478

    
479
        Code code = compiler.compileExpression(source.toString());
480
        link(code);
481
        checkEquals("testSelectWhereOrderLimit", "( SELECT * FROM \"countries\" WHERE (\"LASTCENSUS\" > 0) ORDER BY \"LASTCENSUS\" DESC NULLS LAST LIMIT 3 )", code.toString());
482
    }
483

    
484
    public void testSelectWhereOrderNullsLastLimit() {
485
        StringBuilder source = new StringBuilder();
486
        source.append("SELECT * FROM countries  ");
487
        source.append("  WHERE LASTCENSUS > 0  ");
488
        source.append("  ORDER BY LASTCENSUS DESC NULLS LAST");
489
        source.append("  LIMIT 3");
490

    
491
        Compiler compiler = createCompiler();
492

    
493
        Code code = compiler.compileExpression(source.toString());
494
        link(code);
495
        checkEquals("testSelectWhereOrderLimit", "( SELECT * FROM \"countries\" WHERE (\"LASTCENSUS\" > 0) ORDER BY \"LASTCENSUS\" DESC NULLS LAST LIMIT 3 )", code.toString());
496
    }
497

    
498
    public void testSelectWhereOrderNullsFirstLimit() {
499
        StringBuilder source = new StringBuilder();
500
        source.append("SELECT * FROM countries  ");
501
        source.append("  WHERE LASTCENSUS > 0  ");
502
        source.append("  ORDER BY LASTCENSUS DESC NULLS FIRST");
503
        source.append("  LIMIT 3");
504

    
505
        Compiler compiler = createCompiler();
506

    
507
        Code code = compiler.compileExpression(source.toString());
508
        link(code);
509
        checkEquals("testSelectWhereOrderLimit", "( SELECT * FROM \"countries\" WHERE (\"LASTCENSUS\" > 0) ORDER BY \"LASTCENSUS\" DESC NULLS LAST LIMIT 3 )", code.toString());
510
    }
511

    
512
    public void testSelectWhereOrderLimit2() {
513
        try {
514
            StringBuilder source = new StringBuilder();
515
            source.append("((((GETATTR(\"ARENA2_ACCIDENTES\", 'TITULARIDAD_VIA') = 2) AND (GETATTR(\"ARENA2_ACCIDENTES\", 'FECHA_ACCIDENTE') >= DATE('2020-01-01'))) AND (GETATTR(\"ARENA2_ACCIDENTES\", 'FECHA_ACCIDENTE') <= DATE('2020-12-31'))) AND (EXISTS(SELECT(\"LID_ACCIDENTE\", \"ARENA2_VEHICULOS\", ((GETATTR(\"ARENA2_VEHICULOS\", 'ID_ACCIDENTE') = GETATTR(\"ARENA2_ACCIDENTES\", 'LID_ACCIDENTE')) AND (GETATTR(\"ARENA2_VEHICULOS\", 'TIPO_VEHICULO') = 4)), TUPLE(), TUPLE(), 1), 'EXISTSaa58b804d9094968ba04664f0c4c8553') OR EXISTS(SELECT(\"LID_ACCIDENTE\", \"ARENA2_VEHICULOS\", ((GETATTR(\"ARENA2_VEHICULOS\", 'ID_ACCIDENTE') = GETATTR(\"ARENA2_ACCIDENTES\", 'LID_ACCIDENTE')) AND (GETATTR(\"ARENA2_VEHICULOS\", 'TIPO_VEHICULO') = 30)), TUPLE(), TUPLE(), 1), 'EXISTSb67e753993c54d1da722ff25a00c2a02')))");
516

    
517
            Compiler compiler = createCompiler();
518

    
519
            Code code = compiler.compileExpression(source.toString());
520
            link(code);
521
            checkEquals("((((\"ARENA2_ACCIDENTES\".\"TITULARIDAD_VIA\" = 2) AND (\"ARENA2_ACCIDENTES\".\"FECHA_ACCIDENTE\" >= DATE('2020-01-01'))) AND (\"ARENA2_ACCIDENTES\".\"FECHA_ACCIDENTE\" <= DATE('2020-12-31'))) AND (EXISTS((SELECT \"LID_ACCIDENTE\"  FROM \"ARENA2_VEHICULOS\" WHERE ((\"ARENA2_VEHICULOS\".\"ID_ACCIDENTE\" = \"ARENA2_ACCIDENTES\".\"LID_ACCIDENTE\") AND (\"ARENA2_VEHICULOS\".\"TIPO_VEHICULO\" = 4)) LIMIT 1), 'EXISTSaa58b804d9094968ba04664f0c4c8553') OR EXISTS((SELECT \"LID_ACCIDENTE\"  FROM \"ARENA2_VEHICULOS\" WHERE ((\"ARENA2_VEHICULOS\".\"ID_ACCIDENTE\" = \"ARENA2_ACCIDENTES\".\"LID_ACCIDENTE\") AND (\"ARENA2_VEHICULOS\".\"TIPO_VEHICULO\" = 30)) LIMIT 1), 'EXISTSb67e753993c54d1da722ff25a00c2a02')))", code.toString());
522
        } catch (Exception ex) {
523
            ex.printStackTrace();
524
            throw ex;
525
        }
526
    }
527
    
528
    public void testSelectLimit() {
529
        StringBuilder source = new StringBuilder();
530
        source.append("SELECT * FROM countries  ");
531
        source.append("  LIMIT 3");
532

    
533
        Compiler compiler = createCompiler();
534

    
535
        Code code = compiler.compileExpression(source.toString());
536
        link(code);
537
        checkEquals("testSelectLimit", "( SELECT * FROM \"countries\" LIMIT 3 )", code.toString());
538
    }
539

    
540
    public void testExists() {
541
        StringBuilder source = new StringBuilder();
542
        source.append("EXISTS(NULL)");
543

    
544
        Compiler compiler = createCompiler();
545

    
546
        Code code = compiler.compileExpression(source.toString());
547
        link(code);
548
        checkEquals("testExists", "EXISTS(NULL, 'EXISTS0123456789abcdef')", replaceExists(code));
549
    }
550

    
551
    public void testExistsSelect1() {
552
        StringBuilder source = new StringBuilder();
553
        source.append("EXISTS(");
554
        source.append(" SELECT \"ISO_A2\" FROM countries");
555
        source.append("   WHERE countries.LASTCENSUS > 0 ");
556
        source.append(")");
557

    
558
        Compiler compiler = createCompiler();
559

    
560
        Code code = compiler.compileExpression(source.toString());
561
        checkEquals("testExistsSelect1-1", "EXISTS(SELECT(\"ISO_A2\", \"countries\", (GETATTR(\"countries\", 'LASTCENSUS') > 0), TUPLE(), TUPLE(), NULL), 'EXISTS0123456789abcdef')", replaceExists(code));
562
        link(code);
563
        checkEquals("testExistsSelect1-2", "EXISTS(( SELECT \"countries\".\"ISO_A2\" FROM \"countries\" WHERE (\"countries\".\"LASTCENSUS\" > 0) ), 'EXISTS0123456789abcdef')", replaceExists(code));
564
    }
565

    
566
    public void testExistsSelect2() {
567
        StringBuilder source = new StringBuilder();
568
        source.append("EXISTS(");
569
        source.append(" SELECT \"ISO_A2\" FROM countries");
570
        source.append("   WHERE countries.LASTCENSUS > 0 ");
571
        source.append(")");
572

    
573
        Compiler compiler = createCompiler();
574

    
575
        Code code = compiler.compileExpression(source.toString());
576
        link(code);
577
        checkEquals("testExistsSelect2", "EXISTS(( SELECT \"countries\".\"ISO_A2\" FROM \"countries\" WHERE (\"countries\".\"LASTCENSUS\" > 0) ), 'EXISTS0123456789abcdef')", replaceExists(code));
578
    }
579

    
580
    public void testExistsSelect2b() {
581
        StringBuilder source = new StringBuilder();
582
        source.append("EXISTS(");
583
        source.append(" SELECT \"ISO_A2\", \"ISO_A3\" FROM countries");
584
        source.append("   WHERE countries.LASTCENSUS > 0; ");
585
        source.append(")");
586

    
587
        Compiler compiler = createCompiler();
588
        compiler.addCompatibility("SELECT","OPTIONAL_SEMICOLON_AT_END");
589

    
590
        Code code = compiler.compileExpression(source.toString());
591
        link(code);
592
        String source2 = replaceExists(code);
593
        checkEquals("testExistsSelect2b-1", "EXISTS(( SELECT \"countries\".\"ISO_A2\", \"countries\".\"ISO_A3\" FROM \"countries\" WHERE (\"countries\".\"LASTCENSUS\" > 0) ), 'EXISTS0123456789abcdef')", source2);
594
        
595
        ExpressionBuilder builder = ExpressionUtils.createExpressionBuilder();
596
        builder.setProperty(PROP_SQLBUILDER, new SQLBuilderBase());        
597
        checkEquals("testExistsSelect2b-2", "EXISTS(( SELECT \"countries\".\"ISO_A2\", \"countries\".\"ISO_A3\" FROM \"countries\" WHERE (\"countries\".\"LASTCENSUS\" > 0) ), 'EXISTS0123456789abcdef')", replaceExists(code.toValue(builder).toString()));
598
        
599
        Code code2 = compiler.compileExpression(source2);
600
        link(code2);
601
        checkEquals("testExistsSelect2b-3", "EXISTS(( SELECT \"countries\".\"ISO_A2\", \"countries\".\"ISO_A3\" FROM \"countries\" WHERE (\"countries\".\"LASTCENSUS\" > 0) ), 'EXISTS0123456789abcdef')", code2.toString());
602
    }
603

    
604
    public void testExistsSelect2c() {
605
        StringBuilder source = new StringBuilder();
606
        source.append("EXISTS(");
607
        source.append(" SELECT \"ISO_A2\" FROM countries");
608
        source.append("   WHERE countries.LASTCENSUS > 0; ");
609
        source.append(")");
610

    
611
        Compiler compiler = createCompiler();
612
        compiler.addCompatibility("SELECT","OPTIONAL_SEMICOLON_AT_END");
613

    
614
        Code code = compiler.compileExpression(source.toString());
615
        link(code);
616
        String source2 = replaceExists(code);
617
        checkEquals("testExistsSelect2c-1", "EXISTS(( SELECT \"countries\".\"ISO_A2\" FROM \"countries\" WHERE (\"countries\".\"LASTCENSUS\" > 0) ), 'EXISTS0123456789abcdef')", source2);
618
        Code code2 = compiler.compileExpression(source2);
619
        link(code2);
620
        checkEquals("testExistsSelect2c-2", "EXISTS(( SELECT \"countries\".\"ISO_A2\" FROM \"countries\" WHERE (\"countries\".\"LASTCENSUS\" > 0) ), 'EXISTS0123456789abcdef')", code2.toString());
621
    }
622

    
623
    public void testExistsSelectLimit1() {
624
        StringBuilder source = new StringBuilder();
625
        source.append("EXISTS(");
626
        source.append(" SELECT \"ISO_A2\" FROM countries  ");
627
        source.append("   WHERE countries.LASTCENSUS > 0  ");
628
        source.append("   LIMIT 1");
629
        source.append(")");
630

    
631
        Compiler compiler = createCompiler();
632

    
633
        Code code = compiler.compileExpression(source.toString());
634
        link(code);
635
        checkEquals("testExistsSelectLimit1", "EXISTS(( SELECT \"countries\".\"ISO_A2\" FROM \"countries\" WHERE (\"countries\".\"LASTCENSUS\" > 0) LIMIT 1 ), 'EXISTS0123456789abcdef')", replaceExists(code));
636
    }
637

    
638
    public void testExistsSelectLimit2() {
639
        // Sobre la tabla de continentes, para obtener la lista de continentes 
640
        // que tienen paises sin censo.
641
        // Filtramos continentes por un campo del pais.
642
        StringBuilder source = new StringBuilder();
643
        source.append("EXISTS(");
644
        source.append(" SELECT \"ISO_A2\" FROM countries");
645
        source.append("   WHERE ");
646
        source.append("     continents.NAME = countries.CONTINENT AND ");
647
        source.append("     countries.LASTCENSUS < 0 ");
648
        source.append("   LIMIT 1 ");
649
        source.append(")");
650

    
651
        Compiler compiler = createCompiler();
652

    
653
        Code code = compiler.compileExpression(source.toString());
654
        link(code);
655
        checkEquals("testExistsSelectLimit2", "EXISTS(( SELECT \"countries\".\"ISO_A2\" FROM \"countries\" WHERE ((\"continents\".\"NAME\" = \"countries\".\"CONTINENT\") AND (\"countries\".\"LASTCENSUS\" < 0)) LIMIT 1 ), 'EXISTS0123456789abcdef')", replaceExists(code));
656
    }
657

    
658
    public void testExistsSelectLimit3() {
659
        // Sobre la tabla de continentes, para obtener la lista de continentes 
660
        // que tienen paises sin censo.
661
        // Filtramos continentes por un campo del pais.
662
        StringBuilder source = new StringBuilder();
663
        source.append("EXISTS(");
664
        source.append(" SELECT \"ISO_A2\" FROM countries");
665
        source.append("   WHERE ");
666
        source.append("     continents.NAME = countries.CONTINENT AND ");
667
        source.append("     countries.LASTCENSUS < 0 ");
668
        source.append("   LIMIT 1 ");
669
        source.append(" ,");
670
        source.append(" 'patata'");
671
        source.append(")");
672

    
673
        Compiler compiler = createCompiler();
674

    
675
        Code code = compiler.compileExpression(source.toString());
676
        link(code);
677
        checkEquals("testExistsSelectLimit3", "EXISTS(( SELECT \"countries\".\"ISO_A2\" FROM \"countries\" WHERE ((\"continents\".\"NAME\" = \"countries\".\"CONTINENT\") AND (\"countries\".\"LASTCENSUS\" < 0)) LIMIT 1 ), 'patata')", code.toString());
678
    }
679

    
680
    public void testSelectFromSelection() {
681
        StringBuilder source = new StringBuilder();
682
        source.append("SELECT * FROM SELECTION OF countries");
683

    
684
        Compiler compiler = createCompiler();
685

    
686
        Code code = compiler.compileExpression(source.toString());
687
        link(code);
688
        checkEquals("testSelectFromSelection", "( SELECT * FROM SELECTION OF \"countries\" )", code.toString());
689
    }
690

    
691
    public void testSelectFromSelection4() {
692
        StringBuilder source = new StringBuilder();
693
        source.append("BEGIN ");
694
        source.append("  SET X = 0; ");
695
        source.append("  FOR row in SELECT * FROM SELECTION OF countries ");
696
        source.append("    LOOP ");
697
        source.append("      IF row.LASTCENSUS > 0 THEN ");
698
        source.append("        SET X = X + row.LASTCENSUS ");
699
        source.append("      END IF ");
700
        source.append("    END LOOP ");
701
        source.append("END");
702

    
703
        Compiler compiler = createCompiler();
704

    
705
        Code code = compiler.compileExpression(source.toString());
706
        checkEquals("testSelectFromSelection4-1", "BLOCK(LET('X', 0), FOREACH('row', SELECT(TUPLE(), \"countries\", NULL, TUPLE(), TUPLE(), NULL, 1), IF((GETATTR(\"row\", 'LASTCENSUS') > 0), LET('X', (\"X\" + GETATTR(\"row\", 'LASTCENSUS'))))))", code.toString());
707
        link(code);
708
        String source2 = code.toString();
709
        checkEquals("testSelectFromSelection4-2", "BEGIN \"X\" := 0; FOR \"row\" IN ( SELECT * FROM SELECTION OF \"countries\" ) LOOP IF (\"row\".\"LASTCENSUS\" > 0) THEN \"X\" := (\"X\" + \"row\".\"LASTCENSUS\"); END IF END LOOP; END ", source2);
710
        Code code2 = compiler.compileExpression(source2);
711
        checkEquals("testSelectFromSelection4-3", "BLOCK(LET('X', 0), FOREACH('row', SELECT(TUPLE(), \"countries\", NULL, TUPLE(), TUPLE(), NULL, 1), IF((GETATTR(\"row\", 'LASTCENSUS') > 0), LET('X', (\"X\" + GETATTR(\"row\", 'LASTCENSUS'))))))", code2.toString());
712
        link(code2);
713
        checkEquals("testSelectFromSelection4-4", "BEGIN \"X\" := 0; FOR \"row\" IN ( SELECT * FROM SELECTION OF \"countries\" ) LOOP IF (\"row\".\"LASTCENSUS\" > 0) THEN \"X\" := (\"X\" + \"row\".\"LASTCENSUS\"); END IF END LOOP; END ", code2.toString());
714
        
715
    }
716

    
717
    public void testUseCase1() {
718
        try {
719
            String source = 
720
                "BEGIN\n" +
721
                "    IF urbanroads IS NULL THEN\n" +
722
                "        calle := NULL;\n" +
723
                "        urbanroadtype := NULL;\n" +
724
                "        \n" +
725
                "        IF thegeometry IS NULL THEN\n" +
726
                "            RETURN TRUE;\n" +
727
                "        END IF;\n" +
728
                "        SELECT * INTO calle FROM \"ISIROAD_URBANROADS\" \n" +
729
                "            ORDER BY ST_DISTANCE(\"ISIROAD_URBANROADS\".\"Geometria\", thegeometry) \n" +
730
                "            LIMIT 1;\n" +
731
                "        IF calle IS NULL THEN\n" +
732
                "            RETURN TRUE;\n" +
733
                "        END IF;\n" +
734
                "        urbanroads := calle.Id;\n" +
735
                "        \n" +
736
                "        SELECT * INTO tipodecalle FROM \"ISIROAD_URBANROADTYPES\" \n" +
737
                "            WHERE \"ISIROAD_URBANROADTYPES\".\"DESCRIPTION\" = :(calle.Descripcion)\n" +
738
                "            LIMIT 1;    \n" +
739
                "        urbanroadtype := tipodecalle.CODE;\n" +
740
                "    END IF;\n" +
741
                "    TRUE;\n" +
742
                "EXCEPT\n" +
743
                "  print('Error en el calculo de calle de horizontal');\n" +
744
                "  TRUE;\n" +
745
                "END";
746

    
747
            Formatter formatter = new Code.EmptyFormatter(true, 4);
748

    
749
            Compiler compiler = createCompiler();
750
            Code code = compiler.compileExpression(source);
751
            code.link();
752
            checkEquals(
753
                "BEGIN \n" +
754
                "    IF (\"urbanroads\" IS NULL) THEN \n" +
755
                "        \"calle\" := NULL; \n" +
756
                "        \"urbanroadtype\" := NULL; \n" +
757
                "        IF (\"thegeometry\" IS NULL) THEN \n" +
758
                "            RETURN TRUE; \n" +
759
                "        END IF; \n" +
760
                "        ( SELECT * INTO calle FROM \"ISIROAD_URBANROADS\" ORDER BY ST_Distance(\"ISIROAD_URBANROADS\".\"Geometria\", \"thegeometry\") ASC NULLS LAST LIMIT 1 ); \n" +
761
                "        IF (\"calle\" IS NULL) THEN \n" +
762
                "            RETURN TRUE; \n" +
763
                "        END IF; \n" +
764
                "        \"urbanroads\" := \"calle\".\"Id\"; \n" +
765
                "        ( SELECT * INTO tipodecalle FROM \"ISIROAD_URBANROADTYPES\" WHERE (\"ISIROAD_URBANROADTYPES\".\"DESCRIPTION\" = $HOSTEXPRESSION(\"calle\".\"Descripcion\")) LIMIT 1 ); \n" +
766
                "        \"urbanroadtype\" := \"tipodecalle\".\"CODE\"; \n" +
767
                "    END IF; \n" +
768
                "    TRUE; \n" +
769
                "EXCEPT \n" +
770
                "    print('Error en el calculo de calle de horizontal'); \n" +
771
                "    TRUE; \n" +
772
                "END \n", 
773
                code.toString(formatter));
774
        } catch(Exception ex) {
775
            LOGGER.warn("", ex);
776
            throw ex;
777
        }
778
    }
779
    
780
    
781
    
782
}