예제 #1
0
 /**
  * Changes the first coordinate of this POINT function.
  *
  * @param coord1 Its new first coordinate.
  * @throws NullPointerException If the given operand is <i>null</i>.
  * @throws Exception If the given operand is not numeric.
  */
 public void setCoord1(ADQLOperand coord1) throws NullPointerException, Exception {
   if (coord1 == null)
     throw new NullPointerException(
         "The first coordinate of a POINT function must be different from NULL !");
   else if (!coord1.isNumeric())
     throw new Exception("Coordinates of a POINT function must be numeric !");
   else {
     this.coord1 = coord1;
     setPosition(null);
   }
 }
예제 #2
0
  @Test
  public void testTypesChecking() {
    // DECLARE A SIMPLE PARSER:
    ADQLParser parser = new ADQLParser(new DBChecker(tables));

    // Test the type of columns generated by the parser:
    try {
      ADQLQuery query = parser.parseQuery("SELECT colS, colI, colG FROM foo;");
      ADQLOperand colS = query.getSelect().get(0).getOperand();
      ADQLOperand colI = query.getSelect().get(1).getOperand();
      ADQLOperand colG = query.getSelect().get(2).getOperand();
      // test string column:
      assertTrue(colS instanceof ADQLColumn);
      assertTrue(colS.isString());
      assertFalse(colS.isNumeric());
      assertFalse(colS.isGeometry());
      // test integer column:
      assertTrue(colI instanceof ADQLColumn);
      assertFalse(colI.isString());
      assertTrue(colI.isNumeric());
      assertFalse(colI.isGeometry());
      // test geometry column:
      assertTrue(colG instanceof ADQLColumn);
      assertFalse(colG.isString());
      assertFalse(colG.isNumeric());
      assertTrue(colG.isGeometry());
    } catch (ParseException e1) {
      if (e1 instanceof UnresolvedIdentifiersException)
        ((UnresolvedIdentifiersException) e1).getErrors().next().printStackTrace();
      else e1.printStackTrace();
      fail("This query contains known columns: this test should have succeeded!");
    }

    // Test the expected type - NUMERIC - generated by the parser:
    try {
      assertNotNull(parser.parseQuery("SELECT colI * 3 FROM foo;"));
    } catch (ParseException e) {
      e.printStackTrace();
      fail("This query contains a product between 2 numerics: this test should have succeeded!");
    }
    try {
      parser.parseQuery("SELECT colS * 3 FROM foo;");
      fail(
          "This query contains a product between a string and an integer: this test should have failed!");
    } catch (ParseException e) {
      assertTrue(e instanceof UnresolvedIdentifiersException);
      UnresolvedIdentifiersException ex = (UnresolvedIdentifiersException) e;
      assertEquals(1, ex.getNbErrors());
      assertEquals(
          "Type mismatch! A numeric value was expected instead of \"colS\".",
          ex.getErrors().next().getMessage());
    }
    try {
      parser.parseQuery("SELECT colG * 3 FROM foo;");
      fail(
          "This query contains a product between a geometry and an integer: this test should have failed!");
    } catch (ParseException e) {
      assertTrue(e instanceof UnresolvedIdentifiersException);
      UnresolvedIdentifiersException ex = (UnresolvedIdentifiersException) e;
      assertEquals(1, ex.getNbErrors());
      assertEquals(
          "Type mismatch! A numeric value was expected instead of \"colG\".",
          ex.getErrors().next().getMessage());
    }

    // Test the expected type - STRING - generated by the parser:
    try {
      assertNotNull(parser.parseQuery("SELECT colS || 'blabla' FROM foo;"));
    } catch (ParseException e) {
      e.printStackTrace();
      fail(
          "This query contains a concatenation between 2 strings: this test should have succeeded!");
    }
    try {
      parser.parseQuery("SELECT colI || 'blabla' FROM foo;");
      fail(
          "This query contains a concatenation between an integer and a string: this test should have failed!");
    } catch (ParseException e) {
      assertTrue(e instanceof UnresolvedIdentifiersException);
      UnresolvedIdentifiersException ex = (UnresolvedIdentifiersException) e;
      assertEquals(1, ex.getNbErrors());
      assertEquals(
          "Type mismatch! A string value was expected instead of \"colI\".",
          ex.getErrors().next().getMessage());
    }
    try {
      parser.parseQuery("SELECT colG || 'blabla' FROM foo;");
      fail(
          "This query contains a concatenation between a geometry and a string: this test should have failed!");
    } catch (ParseException e) {
      assertTrue(e instanceof UnresolvedIdentifiersException);
      UnresolvedIdentifiersException ex = (UnresolvedIdentifiersException) e;
      assertEquals(1, ex.getNbErrors());
      assertEquals(
          "Type mismatch! A string value was expected instead of \"colG\".",
          ex.getErrors().next().getMessage());
    }

    // Test the expected type - GEOMETRY - generated by the parser:
    try {
      assertNotNull(parser.parseQuery("SELECT CONTAINS(colG, CIRCLE('', 1, 2, 5)) FROM foo;"));
    } catch (ParseException e) {
      e.printStackTrace();
      fail(
          "This query contains a geometrical predicate between 2 geometries: this test should have succeeded!");
    }
    try {
      parser.parseQuery("SELECT CONTAINS(colI, CIRCLE('', 1, 2, 5)) FROM foo;");
      fail(
          "This query contains a geometrical predicate between an integer and a geometry: this test should have failed!");
    } catch (ParseException e) {
      assertTrue(e instanceof UnresolvedIdentifiersException);
      UnresolvedIdentifiersException ex = (UnresolvedIdentifiersException) e;
      assertEquals(1, ex.getNbErrors());
      assertEquals(
          "Type mismatch! A geometry was expected instead of \"colI\".",
          ex.getErrors().next().getMessage());
    }
    try {
      parser.parseQuery("SELECT CONTAINS(colS, CIRCLE('', 1, 2, 5)) FROM foo;");
      fail(
          "This query contains a geometrical predicate between a string and a geometry: this test should have failed!");
    } catch (ParseException e) {
      assertTrue(e instanceof UnresolvedIdentifiersException);
      UnresolvedIdentifiersException ex = (UnresolvedIdentifiersException) e;
      assertEquals(1, ex.getNbErrors());
      assertEquals(
          "Type mismatch! A geometry was expected instead of \"colS\".",
          ex.getErrors().next().getMessage());
    }

    // DECLARE SOME UDFs:
    FunctionDef[] udfs =
        new FunctionDef[] {
          new FunctionDef("toto", new DBType(DBDatatype.VARCHAR)),
          new FunctionDef("tata", new DBType(DBDatatype.INTEGER)),
          new FunctionDef("titi", new DBType(DBDatatype.REGION))
        };
    parser = new ADQLParser(new DBChecker(tables, Arrays.asList(udfs)));

    // Test the return type of the function TOTO generated by the parser:
    try {
      ADQLQuery query = parser.parseQuery("SELECT toto() FROM foo;");
      ADQLOperand fct = query.getSelect().get(0).getOperand();
      assertTrue(fct instanceof DefaultUDF);
      assertNotNull(((DefaultUDF) fct).getDefinition());
      assertTrue(fct.isString());
      assertFalse(fct.isNumeric());
      assertFalse(fct.isGeometry());
    } catch (ParseException e1) {
      e1.printStackTrace();
      fail("This query contains a DECLARED UDF: this test should have succeeded!");
    }

    // Test the return type checking inside a whole query:
    try {
      assertNotNull(parser.parseQuery("SELECT toto() || 'Blabla ' AS \"SuperText\" FROM foo;"));
    } catch (ParseException e1) {
      e1.printStackTrace();
      fail(
          "This query contains a DECLARED UDF concatenated to a String: this test should have succeeded!");
    }
    try {
      parser.parseQuery("SELECT toto()*3 AS \"SuperError\" FROM foo;");
      fail(
          "This query contains a DECLARED UDF BUT used as numeric...which is here not possible: this test should have failed!");
    } catch (ParseException e1) {
      assertTrue(e1 instanceof UnresolvedIdentifiersException);
      UnresolvedIdentifiersException ex = (UnresolvedIdentifiersException) e1;
      assertEquals(1, ex.getNbErrors());
      assertEquals(
          "Type mismatch! A numeric value was expected instead of \"toto()\".",
          ex.getErrors().next().getMessage());
    }

    // Test the return type of the function TATA generated by the parser:
    try {
      ADQLQuery query = parser.parseQuery("SELECT tata() FROM foo;");
      ADQLOperand fct = query.getSelect().get(0).getOperand();
      assertTrue(fct instanceof DefaultUDF);
      assertNotNull(((DefaultUDF) fct).getDefinition());
      assertFalse(fct.isString());
      assertTrue(fct.isNumeric());
      assertFalse(fct.isGeometry());
    } catch (ParseException e1) {
      e1.printStackTrace();
      fail("This query contains a DECLARED UDF: this test should have succeeded!");
    }

    // Test the return type checking inside a whole query:
    try {
      assertNotNull(parser.parseQuery("SELECT tata()*3 AS \"aNumeric\" FROM foo;"));
    } catch (ParseException e1) {
      e1.printStackTrace();
      fail(
          "This query contains a DECLARED UDF multiplicated by 3: this test should have succeeded!");
    }
    try {
      parser.parseQuery("SELECT 'Blabla ' || tata() AS \"SuperError\" FROM foo;");
      fail(
          "This query contains a DECLARED UDF BUT used as string...which is here not possible: this test should have failed!");
    } catch (ParseException e1) {
      assertTrue(e1 instanceof UnresolvedIdentifiersException);
      UnresolvedIdentifiersException ex = (UnresolvedIdentifiersException) e1;
      assertEquals(1, ex.getNbErrors());
      assertEquals(
          "Type mismatch! A string value was expected instead of \"tata()\".",
          ex.getErrors().next().getMessage());
    }
    try {
      parser.parseQuery("SELECT tata() || 'Blabla ' AS \"SuperError\" FROM foo;");
      fail(
          "This query contains a DECLARED UDF BUT used as string...which is here not possible: this test should have failed!");
    } catch (ParseException e1) {
      assertTrue(e1 instanceof UnresolvedIdentifiersException);
      UnresolvedIdentifiersException ex = (UnresolvedIdentifiersException) e1;
      assertEquals(1, ex.getNbErrors());
      assertEquals(
          "Type mismatch! A string value was expected instead of \"tata()\".",
          ex.getErrors().next().getMessage());
    }

    // Test the return type of the function TITI generated by the parser:
    try {
      ADQLQuery query = parser.parseQuery("SELECT titi() FROM foo;");
      ADQLOperand fct = query.getSelect().get(0).getOperand();
      assertTrue(fct instanceof DefaultUDF);
      assertNotNull(((DefaultUDF) fct).getDefinition());
      assertFalse(fct.isString());
      assertFalse(fct.isNumeric());
      assertTrue(fct.isGeometry());
    } catch (ParseException e1) {
      e1.printStackTrace();
      fail("This query contains a DECLARED UDF: this test should have succeeded!");
    }

    // Test the return type checking inside a whole query:
    try {
      parser.parseQuery("SELECT CONTAINS(colG, titi()) ' AS \"Super\" FROM foo;");
      fail(
          "Geometrical UDFs are not allowed for the moment in the ADQL language: this test should have failed!");
    } catch (ParseException e1) {
      assertTrue(e1 instanceof ParseException);
      assertEquals(
          " Encountered \"(\". Was expecting one of: \")\" \".\" \".\" \")\" ", e1.getMessage());
    }
    try {
      parser.parseQuery("SELECT titi()*3 AS \"SuperError\" FROM foo;");
      fail(
          "This query contains a DECLARED UDF BUT used as numeric...which is here not possible: this test should have failed!");
    } catch (ParseException e1) {
      assertTrue(e1 instanceof UnresolvedIdentifiersException);
      UnresolvedIdentifiersException ex = (UnresolvedIdentifiersException) e1;
      assertEquals(1, ex.getNbErrors());
      assertEquals(
          "Type mismatch! A numeric value was expected instead of \"titi()\".",
          ex.getErrors().next().getMessage());
    }

    // Try with functions wrapped on 2 levels:
    // i.e. fct1('blabla', fct2(fct3('blabla')))
    FunctionDef[] complexFcts = new FunctionDef[3];
    complexFcts[0] =
        new FunctionDef(
            "fct1",
            new DBType(DBDatatype.VARCHAR),
            new FunctionParam[] {
              new FunctionParam("str", new DBType(DBDatatype.VARCHAR)),
              new FunctionParam("num", new DBType(DBDatatype.INTEGER))
            });
    complexFcts[1] =
        new FunctionDef(
            "fct2",
            new DBType(DBDatatype.INTEGER),
            new FunctionParam[] {new FunctionParam("str", new DBType(DBDatatype.VARCHAR))});
    complexFcts[2] =
        new FunctionDef(
            "fct3",
            new DBType(DBDatatype.VARCHAR),
            new FunctionParam[] {new FunctionParam("str", new DBType(DBDatatype.VARCHAR))});
    parser = new ADQLParser(new DBChecker(tables, Arrays.asList(complexFcts)));
    // With parameters of the good type:
    try {
      assertNotNull(parser.parseQuery("SELECT fct1('blabla', fct2(fct3('blabla'))) FROM foo"));
    } catch (ParseException pe) {
      pe.printStackTrace();
      fail("Types are matching: this test should have succeeded!");
    }
    // With parameters of the bad type:
    try {
      parser.parseQuery("SELECT fct2(fct1('blabla', fct3('blabla'))) FROM foo");
      fail("Parameters types are not matching: the parsing should have failed!");
    } catch (ParseException pe) {
      assertEquals(UnresolvedIdentifiersException.class, pe.getClass());
      assertEquals(1, ((UnresolvedIdentifiersException) pe).getNbErrors());
      ParseException innerPe = ((UnresolvedIdentifiersException) pe).getErrors().next();
      assertEquals(
          "Unresolved function: \"fct1('blabla', fct3('blabla'))\"! No UDF has been defined or found with the signature: fct1(STRING, STRING).",
          innerPe.getMessage());
    }

    // CLEAR ALL UDFs AND ALLOW UNKNOWN FUNCTION:
    parser = new ADQLParser(new DBChecker(tables, null));

    // Test again:
    try {
      assertNotNull(parser.parseQuery("SELECT toto() FROM foo;"));
    } catch (ParseException e) {
      e.printStackTrace();
      fail("The parser allow ANY unknown function: this test should have succeeded!");
    }

    // Test the return type of the function generated by the parser:
    try {
      ADQLQuery query = parser.parseQuery("SELECT toto() FROM foo;");
      ADQLOperand fct = query.getSelect().get(0).getOperand();
      assertTrue(fct instanceof DefaultUDF);
      assertNull(((DefaultUDF) fct).getDefinition());
      assertTrue(fct.isString());
      assertTrue(fct.isNumeric());
    } catch (ParseException e1) {
      e1.printStackTrace();
      fail("The parser allow ANY unknown function: this test should have succeeded!");
    }

    // DECLARE THE UDF (while unknown functions are allowed):
    parser =
        new ADQLParser(
            new DBChecker(
                tables,
                Arrays.asList(
                    new FunctionDef[] {new FunctionDef("toto", new DBType(DBDatatype.VARCHAR))})));

    // Test the return type of the function generated by the parser:
    try {
      ADQLQuery query = parser.parseQuery("SELECT toto() FROM foo;");
      ADQLOperand fct = query.getSelect().get(0).getOperand();
      assertTrue(fct instanceof DefaultUDF);
      assertNotNull(((DefaultUDF) fct).getDefinition());
      assertTrue(fct.isString());
      assertFalse(fct.isNumeric());
    } catch (ParseException e1) {
      e1.printStackTrace();
      fail("The parser allow ANY unknown function: this test should have succeeded!");
    }

    // DECLARE UDFs WITH SAME NAMES BUT DIFFERENT TYPE OF ARGUMENT:
    udfs =
        new FunctionDef[] {
          new FunctionDef(
              "toto",
              new DBType(DBDatatype.VARCHAR),
              new FunctionParam[] {new FunctionParam("attr", new DBType(DBDatatype.VARCHAR))}),
          new FunctionDef(
              "toto",
              new DBType(DBDatatype.INTEGER),
              new FunctionParam[] {new FunctionParam("attr", new DBType(DBDatatype.INTEGER))}),
          new FunctionDef(
              "toto",
              new DBType(DBDatatype.INTEGER),
              new FunctionParam[] {new FunctionParam("attr", new DBType(DBDatatype.POINT))})
        };
    parser = new ADQLParser(new DBChecker(tables, Arrays.asList(udfs)));

    // Test the return type in function of the parameter:
    try {
      assertNotNull(
          parser.parseQuery(
              "SELECT toto('blabla') AS toto1, toto(123) AS toto2, toto(POINT('', 1, 2)) AS toto3  FROM foo;"));
    } catch (ParseException e1) {
      e1.printStackTrace();
      fail("This query contains two DECLARED UDFs used here: this test should have succeeded!");
    }
    try {
      parser.parseQuery("SELECT toto('blabla') * 123 AS \"SuperError\" FROM foo;");
      fail(
          "This query contains a DECLARED UDF BUT used as numeric...which is here not possible: this test should have failed!");
    } catch (ParseException e) {
      assertTrue(e instanceof UnresolvedIdentifiersException);
      UnresolvedIdentifiersException ex = (UnresolvedIdentifiersException) e;
      assertEquals(1, ex.getNbErrors());
      assertEquals(
          "Type mismatch! A numeric value was expected instead of \"toto('blabla')\".",
          ex.getErrors().next().getMessage());
    }
    try {
      parser.parseQuery("SELECT toto(123) || 'blabla' AS \"SuperError\" FROM foo;");
      fail(
          "This query contains a DECLARED UDF BUT used as string...which is here not possible: this test should have failed!");
    } catch (ParseException e) {
      assertTrue(e instanceof UnresolvedIdentifiersException);
      UnresolvedIdentifiersException ex = (UnresolvedIdentifiersException) e;
      assertEquals(1, ex.getNbErrors());
      assertEquals(
          "Type mismatch! A string value was expected instead of \"toto(123)\".",
          ex.getErrors().next().getMessage());
    }
    try {
      parser.parseQuery("SELECT toto(POINT('', 1, 2)) || 'blabla' AS \"SuperError\" FROM foo;");
      fail(
          "This query contains a DECLARED UDF BUT used as string...which is here not possible: this test should have failed!");
    } catch (ParseException e) {
      assertTrue(e instanceof UnresolvedIdentifiersException);
      UnresolvedIdentifiersException ex = (UnresolvedIdentifiersException) e;
      assertEquals(1, ex.getNbErrors());
      assertEquals(
          "Type mismatch! A string value was expected instead of \"toto(POINT('', 1, 2))\".",
          ex.getErrors().next().getMessage());
    }
  }