SQL: Use declared source for error messages (#37161)

Improve error messages by returning the original SQL statement
declaration instead of trying to reproduce it as the casing and
whitespaces are not preserved accurately leading to small 
differences.

Close #37161
This commit is contained in:
Costin Leau 2019-01-13 01:40:22 +02:00 committed by GitHub
parent 03be4dbaca
commit a4339ec7e9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
51 changed files with 458 additions and 500 deletions

View File

@ -108,7 +108,7 @@ public class RestSqlMultinodeIT extends ESRestTestCase {
private void assertCount(RestClient client, int count) throws IOException { private void assertCount(RestClient client, int count) throws IOException {
Map<String, Object> expected = new HashMap<>(); Map<String, Object> expected = new HashMap<>();
String mode = randomMode(); String mode = randomMode();
expected.put("columns", singletonList(columnInfo(mode, "COUNT(1)", "long", JDBCType.BIGINT, 20))); expected.put("columns", singletonList(columnInfo(mode, "COUNT(*)", "long", JDBCType.BIGINT, 20)));
expected.put("rows", singletonList(singletonList(count))); expected.put("rows", singletonList(singletonList(count)));
Request request = new Request("POST", "/_sql"); Request request = new Request("POST", "/_sql");

View File

@ -60,7 +60,7 @@ public class UserFunctionIT extends ESRestTestCase {
@Before @Before
private void setUpUsers() throws IOException { private void setUpUsers() throws IOException {
int usersCount = name.getMethodName().startsWith("testSingle") ? 1 : randomIntBetween(5, 15); int usersCount = name.getMethodName().startsWith("testSingle") ? 1 : randomIntBetween(5, 15);
users = new ArrayList<String>(usersCount); users = new ArrayList<>(usersCount);
users.addAll(randomUnique(() -> randomAlphaOfLengthBetween(1, 15), usersCount)); users.addAll(randomUnique(() -> randomAlphaOfLengthBetween(1, 15), usersCount));
for (String user : users) { for (String user : users) {
createUser(user, MINIMAL_ACCESS_ROLE); createUser(user, MINIMAL_ACCESS_ROLE);
@ -80,7 +80,7 @@ public class UserFunctionIT extends ESRestTestCase {
Map<String, Object> expected = new HashMap<>(); Map<String, Object> expected = new HashMap<>();
expected.put("columns", Arrays.asList( expected.put("columns", Arrays.asList(
columnInfo(mode, "USER", "keyword", JDBCType.VARCHAR, 0))); columnInfo(mode, "USER()", "keyword", JDBCType.VARCHAR, 0)));
expected.put("rows", Arrays.asList(Arrays.asList(randomUserName))); expected.put("rows", Arrays.asList(Arrays.asList(randomUserName)));
Map<String, Object> actual = runSql(randomUserName, mode, SQL); Map<String, Object> actual = runSql(randomUserName, mode, SQL);
@ -96,7 +96,7 @@ public class UserFunctionIT extends ESRestTestCase {
Map<String, Object> expected = new HashMap<>(); Map<String, Object> expected = new HashMap<>();
expected.put("columns", Arrays.asList( expected.put("columns", Arrays.asList(
columnInfo(mode, "USER", "keyword", JDBCType.VARCHAR, 0))); columnInfo(mode, "USER()", "keyword", JDBCType.VARCHAR, 0)));
expected.put("rows", Arrays.asList(Arrays.asList(randomUserName), expected.put("rows", Arrays.asList(Arrays.asList(randomUserName),
Arrays.asList(randomUserName), Arrays.asList(randomUserName),
Arrays.asList(randomUserName))); Arrays.asList(randomUserName)));
@ -114,7 +114,7 @@ public class UserFunctionIT extends ESRestTestCase {
Map<String, Object> expected = new HashMap<>(); Map<String, Object> expected = new HashMap<>();
expected.put("columns", Arrays.asList( expected.put("columns", Arrays.asList(
columnInfo(mode, "USER", "keyword", JDBCType.VARCHAR, 0))); columnInfo(mode, "USER()", "keyword", JDBCType.VARCHAR, 0)));
expected.put("rows", Collections.<ArrayList<String>>emptyList()); expected.put("rows", Collections.<ArrayList<String>>emptyList());
String anotherRandomUserName = randomValueOtherThan(randomUserName, () -> randomAlphaOfLengthBetween(1, 15)); String anotherRandomUserName = randomValueOtherThan(randomUserName, () -> randomAlphaOfLengthBetween(1, 15));
Map<String, Object> actual = runSql(randomUserName, mode, SQL + " FROM test WHERE USER()='" + anotherRandomUserName + "' LIMIT 3"); Map<String, Object> actual = runSql(randomUserName, mode, SQL + " FROM test WHERE USER()='" + anotherRandomUserName + "' LIMIT 3");
@ -129,7 +129,7 @@ public class UserFunctionIT extends ESRestTestCase {
Map<String, Object> expected = new HashMap<>(); Map<String, Object> expected = new HashMap<>();
expected.put("columns", Arrays.asList( expected.put("columns", Arrays.asList(
columnInfo(mode, "USER", "keyword", JDBCType.VARCHAR, 0))); columnInfo(mode, "USER()", "keyword", JDBCType.VARCHAR, 0)));
expected.put("rows", Arrays.asList(Arrays.asList(randomlyPickedUsername))); expected.put("rows", Arrays.asList(Arrays.asList(randomlyPickedUsername)));
Map<String, Object> actual = runSql(randomlyPickedUsername, mode, SQL); Map<String, Object> actual = runSql(randomlyPickedUsername, mode, SQL);
@ -147,7 +147,7 @@ public class UserFunctionIT extends ESRestTestCase {
Map<String, Object> expected = new HashMap<>(); Map<String, Object> expected = new HashMap<>();
expected.put("columns", Arrays.asList( expected.put("columns", Arrays.asList(
columnInfo(mode, "USER", "keyword", JDBCType.VARCHAR, 0))); columnInfo(mode, "USER()", "keyword", JDBCType.VARCHAR, 0)));
expected.put("rows", Arrays.asList(Arrays.asList(randomUserName), expected.put("rows", Arrays.asList(Arrays.asList(randomUserName),
Arrays.asList(randomUserName), Arrays.asList(randomUserName),
Arrays.asList(randomUserName))); Arrays.asList(randomUserName)));

View File

@ -64,7 +64,7 @@ public class CliExplainIT extends CliIntegrationTestCase {
assertThat(readLine(), startsWith("----------")); assertThat(readLine(), startsWith("----------"));
assertThat(readLine(), startsWith("With[{}]")); assertThat(readLine(), startsWith("With[{}]"));
assertThat(readLine(), startsWith("\\_Project[[?*]]")); assertThat(readLine(), startsWith("\\_Project[[?*]]"));
assertThat(readLine(), startsWith(" \\_Filter[?i == 2]")); assertThat(readLine(), startsWith(" \\_Filter[i = 2#"));
assertThat(readLine(), startsWith(" \\_UnresolvedRelation[[][index=test],null,Unknown index [test]]")); assertThat(readLine(), startsWith(" \\_UnresolvedRelation[[][index=test],null,Unknown index [test]]"));
assertEquals("", readLine()); assertEquals("", readLine());
@ -72,14 +72,14 @@ public class CliExplainIT extends CliIntegrationTestCase {
containsString("plan")); containsString("plan"));
assertThat(readLine(), startsWith("----------")); assertThat(readLine(), startsWith("----------"));
assertThat(readLine(), startsWith("Project[[i{f}#")); assertThat(readLine(), startsWith("Project[[i{f}#"));
assertThat(readLine(), startsWith("\\_Filter[i{f}#")); assertThat(readLine(), startsWith("\\_Filter[i = 2#"));
assertThat(readLine(), startsWith(" \\_EsRelation[test][i{f}#")); assertThat(readLine(), startsWith(" \\_EsRelation[test][i{f}#"));
assertEquals("", readLine()); assertEquals("", readLine());
assertThat(command("EXPLAIN (PLAN OPTIMIZED) SELECT * FROM test WHERE i = 2"), containsString("plan")); assertThat(command("EXPLAIN (PLAN OPTIMIZED) SELECT * FROM test WHERE i = 2"), containsString("plan"));
assertThat(readLine(), startsWith("----------")); assertThat(readLine(), startsWith("----------"));
assertThat(readLine(), startsWith("Project[[i{f}#")); assertThat(readLine(), startsWith("Project[[i{f}#"));
assertThat(readLine(), startsWith("\\_Filter[i{f}#")); assertThat(readLine(), startsWith("\\_Filter[i = 2#"));
assertThat(readLine(), startsWith(" \\_EsRelation[test][i{f}#")); assertThat(readLine(), startsWith(" \\_EsRelation[test][i{f}#"));
assertEquals("", readLine()); assertEquals("", readLine());
@ -124,20 +124,20 @@ public class CliExplainIT extends CliIntegrationTestCase {
assertThat(command("EXPLAIN (PLAN PARSED) SELECT COUNT(*) FROM test"), containsString("plan")); assertThat(command("EXPLAIN (PLAN PARSED) SELECT COUNT(*) FROM test"), containsString("plan"));
assertThat(readLine(), startsWith("----------")); assertThat(readLine(), startsWith("----------"));
assertThat(readLine(), startsWith("With[{}]")); assertThat(readLine(), startsWith("With[{}]"));
assertThat(readLine(), startsWith("\\_Project[[?COUNT(?*)]]")); assertThat(readLine(), startsWith("\\_Project[[?COUNT(*)]]"));
assertThat(readLine(), startsWith(" \\_UnresolvedRelation[[][index=test],null,Unknown index [test]]")); assertThat(readLine(), startsWith(" \\_UnresolvedRelation[[][index=test],null,Unknown index [test]]"));
assertEquals("", readLine()); assertEquals("", readLine());
assertThat(command("EXPLAIN " + (randomBoolean() ? "" : "(PLAN ANALYZED) ") + "SELECT COUNT(*) FROM test"), assertThat(command("EXPLAIN " + (randomBoolean() ? "" : "(PLAN ANALYZED) ") + "SELECT COUNT(*) FROM test"),
containsString("plan")); containsString("plan"));
assertThat(readLine(), startsWith("----------")); assertThat(readLine(), startsWith("----------"));
assertThat(readLine(), startsWith("Aggregate[[],[COUNT(1)#")); assertThat(readLine(), startsWith("Aggregate[[],[COUNT(*)#"));
assertThat(readLine(), startsWith("\\_EsRelation[test][i{f}#")); assertThat(readLine(), startsWith("\\_EsRelation[test][i{f}#"));
assertEquals("", readLine()); assertEquals("", readLine());
assertThat(command("EXPLAIN (PLAN OPTIMIZED) SELECT COUNT(*) FROM test"), containsString("plan")); assertThat(command("EXPLAIN (PLAN OPTIMIZED) SELECT COUNT(*) FROM test"), containsString("plan"));
assertThat(readLine(), startsWith("----------")); assertThat(readLine(), startsWith("----------"));
assertThat(readLine(), startsWith("Aggregate[[],[COUNT(1)#")); assertThat(readLine(), startsWith("Aggregate[[],[COUNT(*)#"));
assertThat(readLine(), startsWith("\\_EsRelation[test][i{f}#")); assertThat(readLine(), startsWith("\\_EsRelation[test][i{f}#"));
assertEquals("", readLine()); assertEquals("", readLine());

View File

@ -20,7 +20,7 @@ import static org.elasticsearch.xpack.sql.qa.jdbc.CsvTestUtils.csvConnection;
import static org.elasticsearch.xpack.sql.qa.jdbc.CsvTestUtils.executeCsvQuery; import static org.elasticsearch.xpack.sql.qa.jdbc.CsvTestUtils.executeCsvQuery;
import static org.elasticsearch.xpack.sql.qa.jdbc.CsvTestUtils.specParser; import static org.elasticsearch.xpack.sql.qa.jdbc.CsvTestUtils.specParser;
@TestLogging(JdbcTestUtils.SQL_TRACE) @TestLogging("org.elasticsearch.xpack.sql:TRACE")
public abstract class DebugCsvSpec extends SpecBaseIntegrationTestCase { public abstract class DebugCsvSpec extends SpecBaseIntegrationTestCase {
private final CsvTestCase testCase; private final CsvTestCase testCase;

View File

@ -169,7 +169,7 @@ FROM "test_emp" GROUP BY "TEMP" ORDER BY "TEMP" LIMIT 20;
aggAndOrderByCastedValue aggAndOrderByCastedValue
SELECT CHAR_LENGTH(SPACE(CAST(languages AS SMALLINT))), COUNT(*) FROM test_emp GROUP BY 1 ORDER BY 1 DESC; SELECT CHAR_LENGTH(SPACE(CAST(languages AS SMALLINT))), COUNT(*) FROM test_emp GROUP BY 1 ORDER BY 1 DESC;
CHAR_LENGTH(SPACE(CAST(languages AS SMALLINT))):i| COUNT(1):l CHAR_LENGTH(SPACE(CAST(languages AS SMALLINT))):i| COUNT(*):l
-------------------------------------------------+--------------- -------------------------------------------------+---------------
5 |21 5 |21
4 |18 4 |18
@ -180,9 +180,9 @@ null |10
; ;
aggAndOrderByCastedFunctionValue aggAndOrderByCastedFunctionValue
SELECT ROUND(SQRT(CAST(EXP(languages) AS SMALLINT)), 2), COUNT(*) FROM test_emp GROUP BY 1 ORDER BY 1 DESC; SELECT ROUND(SQRT(CAST(EXP(languages) AS SMALLINT)),2), COUNT(*) FROM test_emp GROUP BY 1 ORDER BY 1 DESC;
ROUND(SQRT(CAST(EXP(languages) AS SMALLINT)),2):d| COUNT(1):l ROUND(SQRT(CAST(EXP(languages) AS SMALLINT)),2):d| COUNT(*):l
-------------------------------------------------+--------------- -------------------------------------------------+---------------
12.17 |21 12.17 |21
7.42 |18 7.42 |18

View File

@ -1124,8 +1124,8 @@ stringAscii
// tag::stringAscii // tag::stringAscii
SELECT ASCII('Elastic'); SELECT ASCII('Elastic');
ASCII(Elastic) ASCII('Elastic')
--------------- ----------------
69 69
// end::stringAscii // end::stringAscii
; ;
@ -1134,8 +1134,8 @@ stringBitLength
// tag::stringBitLength // tag::stringBitLength
SELECT BIT_LENGTH('Elastic'); SELECT BIT_LENGTH('Elastic');
BIT_LENGTH(Elastic) BIT_LENGTH('Elastic')
------------------- ---------------------
56 56
// end::stringBitLength // end::stringBitLength
; ;
@ -1154,8 +1154,8 @@ stringCharLength
// tag::stringCharLength // tag::stringCharLength
SELECT CHAR_LENGTH('Elastic'); SELECT CHAR_LENGTH('Elastic');
CHAR_LENGTH(Elastic) CHAR_LENGTH('Elastic')
-------------------- ----------------------
7 7
// end::stringCharLength // end::stringCharLength
; ;
@ -1164,8 +1164,8 @@ stringConcat
// tag::stringConcat // tag::stringConcat
SELECT CONCAT('Elasticsearch', ' SQL'); SELECT CONCAT('Elasticsearch', ' SQL');
CONCAT(Elasticsearch, SQL) CONCAT('Elasticsearch', ' SQL')
-------------------------- -------------------------------
Elasticsearch SQL Elasticsearch SQL
// end::stringConcat // end::stringConcat
; ;
@ -1174,8 +1174,8 @@ stringInsert
// tag::stringInsert // tag::stringInsert
SELECT INSERT('Elastic ', 8, 1, 'search'); SELECT INSERT('Elastic ', 8, 1, 'search');
INSERT(Elastic ,8,1,search) INSERT('Elastic ', 8, 1, 'search')
--------------------------- ----------------------------------
Elasticsearch Elasticsearch
// end::stringInsert // end::stringInsert
; ;
@ -1184,8 +1184,8 @@ stringLCase
// tag::stringLCase // tag::stringLCase
SELECT LCASE('Elastic'); SELECT LCASE('Elastic');
LCASE(Elastic) LCASE('Elastic')
--------------- ----------------
elastic elastic
// end::stringLCase // end::stringLCase
; ;
@ -1194,8 +1194,8 @@ stringLeft
// tag::stringLeft // tag::stringLeft
SELECT LEFT('Elastic',3); SELECT LEFT('Elastic',3);
LEFT(Elastic,3) LEFT('Elastic',3)
--------------- -----------------
Ela Ela
// end::stringLeft // end::stringLeft
; ;
@ -1204,8 +1204,8 @@ stringLength
// tag::stringLength // tag::stringLength
SELECT LENGTH('Elastic '); SELECT LENGTH('Elastic ');
LENGTH(Elastic ) LENGTH('Elastic ')
------------------ --------------------
7 7
// end::stringLength // end::stringLength
; ;
@ -1214,8 +1214,8 @@ stringLocateWoStart
// tag::stringLocateWoStart // tag::stringLocateWoStart
SELECT LOCATE('a', 'Elasticsearch'); SELECT LOCATE('a', 'Elasticsearch');
LOCATE(a,Elasticsearch) LOCATE('a', 'Elasticsearch')
----------------------- ----------------------------
3 3
// end::stringLocateWoStart // end::stringLocateWoStart
; ;
@ -1224,8 +1224,8 @@ stringLocateWithStart
// tag::stringLocateWithStart // tag::stringLocateWithStart
SELECT LOCATE('a', 'Elasticsearch', 5); SELECT LOCATE('a', 'Elasticsearch', 5);
LOCATE(a,Elasticsearch,5) LOCATE('a', 'Elasticsearch', 5)
------------------------- -------------------------------
10 10
// end::stringLocateWithStart // end::stringLocateWithStart
; ;
@ -1234,8 +1234,8 @@ stringLTrim
// tag::stringLTrim // tag::stringLTrim
SELECT LTRIM(' Elastic'); SELECT LTRIM(' Elastic');
LTRIM( Elastic) LTRIM(' Elastic')
----------------- -------------------
Elastic Elastic
// end::stringLTrim // end::stringLTrim
; ;
@ -1244,8 +1244,8 @@ stringOctetLength
// tag::stringOctetLength // tag::stringOctetLength
SELECT OCTET_LENGTH('Elastic'); SELECT OCTET_LENGTH('Elastic');
OCTET_LENGTH(Elastic) OCTET_LENGTH('Elastic')
------------------- -----------------------
7 7
// end::stringOctetLength // end::stringOctetLength
; ;
@ -1254,8 +1254,8 @@ stringPosition
// tag::stringPosition // tag::stringPosition
SELECT POSITION('Elastic', 'Elasticsearch'); SELECT POSITION('Elastic', 'Elasticsearch');
POSITION(Elastic,Elasticsearch) POSITION('Elastic', 'Elasticsearch')
------------------------------- ------------------------------------
1 1
// end::stringPosition // end::stringPosition
; ;
@ -1264,8 +1264,8 @@ stringRepeat
// tag::stringRepeat // tag::stringRepeat
SELECT REPEAT('La', 3); SELECT REPEAT('La', 3);
REPEAT(La,3) REPEAT('La', 3)
--------------- ----------------
LaLaLa LaLaLa
// end::stringRepeat // end::stringRepeat
; ;
@ -1274,8 +1274,8 @@ stringReplace
// tag::stringReplace // tag::stringReplace
SELECT REPLACE('Elastic','El','Fant'); SELECT REPLACE('Elastic','El','Fant');
REPLACE(Elastic,El,Fant) REPLACE('Elastic','El','Fant')
----------------------------- ------------------------------
Fantastic Fantastic
// end::stringReplace // end::stringReplace
; ;
@ -1284,8 +1284,8 @@ stringRight
// tag::stringRight // tag::stringRight
SELECT RIGHT('Elastic',3); SELECT RIGHT('Elastic',3);
RIGHT(Elastic,3) RIGHT('Elastic',3)
---------------- ------------------
tic tic
// end::stringRight // end::stringRight
; ;
@ -1294,8 +1294,8 @@ stringRTrim
// tag::stringRTrim // tag::stringRTrim
SELECT RTRIM('Elastic '); SELECT RTRIM('Elastic ');
RTRIM(Elastic ) RTRIM('Elastic ')
----------------- -------------------
Elastic Elastic
// end::stringRTrim // end::stringRTrim
; ;
@ -1316,8 +1316,8 @@ stringSubString
// tag::stringSubString // tag::stringSubString
SELECT SUBSTRING('Elasticsearch', 0, 7); SELECT SUBSTRING('Elasticsearch', 0, 7);
SUBSTRING(Elasticsearch,0,7) SUBSTRING('Elasticsearch', 0, 7)
---------------------------- --------------------------------
Elastic Elastic
// end::stringSubString // end::stringSubString
; ;
@ -1326,8 +1326,8 @@ stringUCase
// tag::stringUCase // tag::stringUCase
SELECT UCASE('Elastic'); SELECT UCASE('Elastic');
UCASE(Elastic) UCASE('Elastic')
--------------- ----------------
ELASTIC ELASTIC
// end::stringUCase // end::stringUCase
; ;
@ -1417,7 +1417,7 @@ mathInlineAcos
// tag::mathInlineAcos // tag::mathInlineAcos
SELECT ACOS(COS(PI())), PI(); SELECT ACOS(COS(PI())), PI();
ACOS(COS(PI)) | PI ACOS(COS(PI())) | PI()
-----------------+----------------- -----------------+-----------------
3.141592653589793|3.141592653589793 3.141592653589793|3.141592653589793
// end::mathInlineAcos // end::mathInlineAcos
@ -1467,8 +1467,8 @@ mathInlineCeiling
// tag::mathInlineCeiling // tag::mathInlineCeiling
SELECT CEIL(125.01), CEILING(-125.99); SELECT CEIL(125.01), CEILING(-125.99);
CEIL(125.01) | CEIL(-125.99) CEIL(125.01) |CEILING(-125.99)
---------------+--------------- ---------------+----------------
126 |-125 126 |-125
// end::mathInlineCeiling // end::mathInlineCeiling
; ;
@ -1507,7 +1507,7 @@ mathInlineDegrees
// tag::mathInlineDegrees // tag::mathInlineDegrees
SELECT DEGREES(PI() * 2), DEGREES(PI()); SELECT DEGREES(PI() * 2), DEGREES(PI());
DEGREES((PI) * 2)| DEGREES(PI) DEGREES(PI() * 2)| DEGREES(PI())
-----------------+--------------- -----------------+---------------
360.0 |180.0 360.0 |180.0
// end::mathInlineDegrees // end::mathInlineDegrees
@ -1517,7 +1517,7 @@ mathEulersNumber
// tag::mathEulersNumber // tag::mathEulersNumber
SELECT E(), CEIL(E()); SELECT E(), CEIL(E());
E | CEIL(E) E() | CEIL(E())
-----------------+--------------- -----------------+---------------
2.718281828459045|3 2.718281828459045|3
// end::mathEulersNumber // end::mathEulersNumber
@ -1527,7 +1527,7 @@ mathExpInline
// tag::mathExpInline // tag::mathExpInline
SELECT EXP(1), E(), EXP(2), E() * E(); SELECT EXP(1), E(), EXP(2), E() * E();
EXP(1) | E | EXP(2) | (E) * (E) EXP(1) | E() | EXP(2) | E() * E()
-----------------+-----------------+----------------+------------------ -----------------+-----------------+----------------+------------------
2.718281828459045|2.718281828459045|7.38905609893065|7.3890560989306495 2.718281828459045|2.718281828459045|7.38905609893065|7.3890560989306495
// end::mathExpInline // end::mathExpInline
@ -1537,7 +1537,7 @@ mathExpm1Inline
// tag::mathExpm1Inline // tag::mathExpm1Inline
SELECT E(), EXP(2), EXPM1(2); SELECT E(), EXP(2), EXPM1(2);
E | EXP(2) | EXPM1(2) E() | EXP(2) | EXPM1(2)
-----------------+----------------+---------------- -----------------+----------------+----------------
2.718281828459045|7.38905609893065|6.38905609893065 2.718281828459045|7.38905609893065|6.38905609893065
// end::mathExpm1Inline // end::mathExpm1Inline
@ -1567,8 +1567,8 @@ mathInlineLog10
// tag::mathInlineLog10 // tag::mathInlineLog10
SELECT LOG10(5), LOG(5)/LOG(10); SELECT LOG10(5), LOG(5)/LOG(10);
LOG10(5) |(LOG(5)) / (LOG(10)) LOG10(5) | LOG(5)/LOG(10)
------------------+-------------------- ------------------+-----------------------
0.6989700043360189|0.6989700043360187 0.6989700043360189|0.6989700043360187
// end::mathInlineLog10 // end::mathInlineLog10
; ;
@ -1577,7 +1577,7 @@ mathPINumber
// tag::mathPINumber // tag::mathPINumber
SELECT PI(); SELECT PI();
PI PI()
----------------- -----------------
3.141592653589793 3.141592653589793
// end::mathPINumber // end::mathPINumber
@ -1587,7 +1587,7 @@ mathInlinePowerPositive
// tag::mathInlinePowerPositive // tag::mathInlinePowerPositive
SELECT POWER(3, 2), POWER(3, 3); SELECT POWER(3, 2), POWER(3, 3);
POWER(3,2) | POWER(3,3) POWER(3, 2) | POWER(3, 3)
---------------+--------------- ---------------+---------------
9.0 |27.0 9.0 |27.0
// end::mathInlinePowerPositive // end::mathInlinePowerPositive
@ -1597,7 +1597,7 @@ mathInlinePowerNegative
// tag::mathInlinePowerNegative // tag::mathInlinePowerNegative
SELECT POWER(5, -1), POWER(5, -2); SELECT POWER(5, -1), POWER(5, -2);
POWER(5,-1) | POWER(5,-2) POWER(5, -1) | POWER(5, -2)
---------------+--------------- ---------------+---------------
0.2 |0.04 0.2 |0.04
// end::mathInlinePowerNegative // end::mathInlinePowerNegative
@ -1607,7 +1607,7 @@ mathInlineRadians
// tag::mathInlineRadians // tag::mathInlineRadians
SELECT RADIANS(90), PI()/2; SELECT RADIANS(90), PI()/2;
RADIANS(90) | (PI) / 2 RADIANS(90) | PI()/2
------------------+------------------ ------------------+------------------
1.5707963267948966|1.5707963267948966 1.5707963267948966|1.5707963267948966
// end::mathInlineRadians // end::mathInlineRadians
@ -1677,7 +1677,7 @@ mathInlineSqrt
// tag::mathInlineSqrt // tag::mathInlineSqrt
SELECT SQRT(EXP(2)), E(), SQRT(25); SELECT SQRT(EXP(2)), E(), SQRT(25);
SQRT(EXP(2)) | E | SQRT(25) SQRT(EXP(2)) | E() | SQRT(25)
-----------------+-----------------+--------------- -----------------+-----------------+---------------
2.718281828459045|2.718281828459045|5.0 2.718281828459045|2.718281828459045|5.0
// end::mathInlineSqrt // end::mathInlineSqrt

View File

@ -263,18 +263,18 @@ SELECT POSITION('x',LCASE("first_name")) pos, "first_name" FROM "test_emp" WHERE
; ;
selectPositionWithLcaseAndConditionWithGroupByAndOrderBy selectPositionWithLcaseAndConditionWithGroupByAndOrderBy
SELECT POSITION('m',LCASE("first_name")), COUNT(*) pos FROM "test_emp" SELECT POSITION('m',LCASE("first_name")) AS pos, COUNT(*) c FROM "test_emp"
WHERE POSITION('m',LCASE("first_name")) != 0 WHERE POSITION('m',LCASE("first_name")) != 0
GROUP BY POSITION('m',LCASE("first_name")) ORDER BY POSITION('m',LCASE("first_name")) DESC; GROUP BY POSITION('m',LCASE("first_name")) ORDER BY POSITION('m',LCASE("first_name")) DESC;
POSITION(m,LCASE(first_name)):i| pos:l pos:i| c:l
-------------------------------+--------------- -----+-----
9 |1 9 |1
7 |1 7 |1
4 |2 4 |2
3 |6 3 |6
2 |1 2 |1
1 |9 1 |9
; ;
selectInsertWithPositionAndCondition selectInsertWithPositionAndCondition
@ -299,8 +299,8 @@ ReMzi |3
selectLocateAndInsertWithLocateWithConditionAndThreeParameters selectLocateAndInsertWithLocateWithConditionAndThreeParameters
SELECT LOCATE('a',"first_name",7) pos, INSERT("first_name",LOCATE('a',"first_name",7),1,'AAA') FROM "test_emp" WHERE LOCATE('a',"first_name",7) > 0; SELECT LOCATE('a',"first_name",7) pos, INSERT("first_name",LOCATE('a',"first_name",7),1,'AAA') FROM "test_emp" WHERE LOCATE('a',"first_name",7) > 0;
pos:i |INSERT(first_name,LOCATE(a,first_name,7),1,AAA):s pos:i |INSERT("first_name",LOCATE('a',"first_name",7),1,'AAA'):s
---------------+----------------------------------------------- ---------------+---------------------------------------------------------
8 |ChirstiAAAn 8 |ChirstiAAAn
7 |DuangkAAAew 7 |DuangkAAAew
8 |PrasadrAAAm 8 |PrasadrAAAm
@ -317,8 +317,8 @@ SELECT LOCATE('a',"first_name",7) pos, INSERT("first_name",LOCATE('a',"first_nam
selectLocateAndInsertWithLocateWithConditionAndTwoParameters selectLocateAndInsertWithLocateWithConditionAndTwoParameters
SELECT LOCATE('a',"first_name") pos, INSERT("first_name",LOCATE('a',"first_name"),1,'AAA') FROM "test_emp" WHERE LOCATE('a',"first_name") > 0 ORDER BY "first_name" LIMIT 10; SELECT LOCATE('a',"first_name") pos, INSERT("first_name",LOCATE('a',"first_name"),1,'AAA') FROM "test_emp" WHERE LOCATE('a',"first_name") > 0 ORDER BY "first_name" LIMIT 10;
pos:i |INSERT(first_name,LOCATE(a,first_name),1,AAA):s pos:i |INSERT("first_name",LOCATE('a',"first_name"),1,'AAA'):s
---------------+--------------------------------------------- ---------------+-------------------------------------------------------
5 |AlejAAAndro 5 |AlejAAAndro
3 |AmAAAbile 3 |AmAAAbile
7 |ArumugAAAm 7 |ArumugAAAm
@ -455,23 +455,23 @@ AlejandRo |1
checkColumnNameWithNestedArithmeticFunctionCallsOnTableColumn checkColumnNameWithNestedArithmeticFunctionCallsOnTableColumn
SELECT CHAR(emp_no % 10000) FROM "test_emp" WHERE emp_no > 10064 ORDER BY emp_no LIMIT 1; SELECT CHAR(emp_no % 10000) AS c FROM "test_emp" WHERE emp_no > 10064 ORDER BY emp_no LIMIT 1;
CHAR((emp_no) % 10000):s c:s
A A
; ;
checkColumnNameWithComplexNestedArithmeticFunctionCallsOnTableColumn1 checkColumnNameWithComplexNestedArithmeticFunctionCallsOnTableColumn1
SELECT CHAR(emp_no % (7000 + 3000)) FROM "test_emp" WHERE emp_no > 10065 ORDER BY emp_no LIMIT 1; SELECT CHAR(emp_no % (7000 + 3000)) AS c FROM "test_emp" WHERE emp_no > 10065 ORDER BY emp_no LIMIT 1;
CHAR((emp_no) % (7000 + 3000)):s c:s
B B
; ;
checkColumnNameWithComplexNestedArithmeticFunctionCallsOnTableColumn2 checkColumnNameWithComplexNestedArithmeticFunctionCallsOnTableColumn2
SELECT CHAR((emp_no % (emp_no - 1 + 1)) + 67) FROM "test_emp" WHERE emp_no > 10066 ORDER BY emp_no LIMIT 1; SELECT CHAR((emp_no % (emp_no - 1 + 1)) + 67) AS c FROM "test_emp" WHERE emp_no > 10066 ORDER BY emp_no LIMIT 1;
CHAR(((emp_no) % (((emp_no) - 1) + 1)) + 67):s c:s
C C
; ;

View File

@ -2,27 +2,27 @@
truncateWithAsciiHavingAndOrderBy truncateWithAsciiHavingAndOrderBy
SELECT TRUNCATE(ASCII(LEFT(first_name, 1)), 1), COUNT(*) count FROM test_emp GROUP BY ASCII(LEFT(first_name, 1)) HAVING COUNT(*) > 5 ORDER BY TRUNCATE(ASCII(LEFT(first_name, 1)), 1) DESC; SELECT TRUNCATE(ASCII(LEFT(first_name, 1)), 1), COUNT(*) count FROM test_emp GROUP BY ASCII(LEFT(first_name, 1)) HAVING COUNT(*) > 5 ORDER BY TRUNCATE(ASCII(LEFT(first_name, 1)), 1) DESC;
TRUNCATE(ASCII(LEFT(first_name,1)),1):i| count:l TRUNCATE(ASCII(LEFT(first_name, 1)), 1):i| count:l
---------------------------------------+--------------- -----------------------------------------+---------------
null |10 null |10
66 |7 66 |7
72 |6 72 |6
75 |7 75 |7
77 |9 77 |9
83 |11 83 |11
; ;
truncateWithNoSecondParameterWithAsciiHavingAndOrderBy truncateWithNoSecondParameterWithAsciiHavingAndOrderBy
SELECT TRUNCATE(ASCII(LEFT(first_name, 1))), COUNT(*) count FROM test_emp GROUP BY ASCII(LEFT(first_name, 1)) HAVING COUNT(*) > 5 ORDER BY TRUNCATE(ASCII(LEFT(first_name, 1))) DESC; SELECT TRUNCATE(ASCII(LEFT(first_name, 1))), COUNT(*) count FROM test_emp GROUP BY ASCII(LEFT(first_name, 1)) HAVING COUNT(*) > 5 ORDER BY TRUNCATE(ASCII(LEFT(first_name, 1))) DESC;
TRUNCATE(ASCII(LEFT(first_name,1)),0):i| count:l TRUNCATE(ASCII(LEFT(first_name, 1))):i| count:l
---------------------------------------+--------------- --------------------------------------+---------------
null |10 null |10
66 |7 66 |7
72 |6 72 |6
75 |7 75 |7
77 |9 77 |9
83 |11 83 |11
; ;
roundWithGroupByAndOrderBy roundWithGroupByAndOrderBy
@ -97,21 +97,21 @@ SELECT MIN(salary) mi, MAX(salary) ma, COUNT(*) c, TRUNCATE(AVG(salary)) tr FROM
minMaxTruncateAndRoundOfAverageWithHavingRoundAndTruncate minMaxTruncateAndRoundOfAverageWithHavingRoundAndTruncate
SELECT MIN(salary) mi, MAX(salary) ma, YEAR(hire_date) year, ROUND(AVG(languages), 1), TRUNCATE(AVG(languages), 1), COUNT(*) FROM test_emp GROUP BY YEAR(hire_date) HAVING ROUND(AVG(languages), 1) > 2.5 AND TRUNCATE(AVG(languages), 1) <= 3.0 ORDER BY YEAR(hire_date); SELECT MIN(salary) mi, MAX(salary) ma, YEAR(hire_date) year, ROUND(AVG(languages), 1), TRUNCATE(AVG(languages), 1), COUNT(*) FROM test_emp GROUP BY YEAR(hire_date) HAVING ROUND(AVG(languages), 1) > 2.5 AND TRUNCATE(AVG(languages), 1) <= 3.0 ORDER BY YEAR(hire_date);
mi:i | ma:i | year:i |ROUND(AVG(languages),1):d|TRUNCATE(AVG(languages),1):d| COUNT(1):l mi:i | ma:i | year:i |ROUND(AVG(languages), 1):d|TRUNCATE(AVG(languages), 1):d| COUNT(*):l
---------------+---------------+---------------+-------------------------+----------------------------+--------------- ---------------+---------------+---------------+--------------------------+-----------------------------+---------------
25324 |70011 |1986 |3.0 |3.0 |15 25324 |70011 |1986 |3.0 |3.0 |15
25945 |73578 |1987 |2.9 |2.8 |9 25945 |73578 |1987 |2.9 |2.8 |9
25976 |74970 |1988 |3.0 |3.0 |13 25976 |74970 |1988 |3.0 |3.0 |13
31120 |71165 |1989 |3.1 |3.0 |12 31120 |71165 |1989 |3.1 |3.0 |12
30404 |58715 |1992 |3.0 |3.0 |3 30404 |58715 |1992 |3.0 |3.0 |3
35742 |67492 |1993 |2.8 |2.7 |4 35742 |67492 |1993 |2.8 |2.7 |4
45656 |45656 |1995 |3.0 |3.0 |1 45656 |45656 |1995 |3.0 |3.0 |1
; ;
minMaxRoundWithHavingRound minMaxRoundWithHavingRound
SELECT MIN(salary) mi, MAX(salary) ma, YEAR(hire_date) year, ROUND(AVG(languages), 1), COUNT(*) FROM test_emp GROUP BY YEAR(hire_date) HAVING ROUND(AVG(languages), 1) > 2.5 ORDER BY YEAR(hire_date); SELECT MIN(salary) mi, MAX(salary) ma, YEAR(hire_date) year, ROUND(AVG(languages),1), COUNT(*) FROM test_emp GROUP BY YEAR(hire_date) HAVING ROUND(AVG(languages), 1) > 2.5 ORDER BY YEAR(hire_date);
mi:i | ma:i | year:i |ROUND(AVG(languages),1):d| COUNT(1):l mi:i | ma:i | year:i |ROUND(AVG(languages),1):d| COUNT(*):l
---------------+---------------+---------------+-------------------------+--------------- ---------------+---------------+---------------+-------------------------+---------------
26436 |74999 |1984 |3.1 |11 26436 |74999 |1984 |3.1 |11
31897 |61805 |1985 |3.5 |11 31897 |61805 |1985 |3.5 |11
@ -127,9 +127,9 @@ SELECT MIN(salary) mi, MAX(salary) ma, YEAR(hire_date) year, ROUND(AVG(languages
; ;
groupByAndOrderByTruncateWithPositiveParameter groupByAndOrderByTruncateWithPositiveParameter
SELECT TRUNCATE(AVG(salary), 2), AVG(salary), COUNT(*) FROM test_emp GROUP BY TRUNCATE(salary, 2) ORDER BY TRUNCATE(salary, 2) DESC LIMIT 10; SELECT TRUNCATE(AVG(salary),2), AVG(salary), COUNT(*) FROM test_emp GROUP BY TRUNCATE(salary, 2) ORDER BY TRUNCATE(salary, 2) DESC LIMIT 10;
TRUNCATE(AVG(salary),2):d| AVG(salary):d | COUNT(1):l TRUNCATE(AVG(salary),2):d| AVG(salary):d | COUNT(*):l
-------------------------+---------------+--------------- -------------------------+---------------+---------------
74999.0 |74999.0 |1 74999.0 |74999.0 |1
74970.0 |74970.0 |1 74970.0 |74970.0 |1
@ -144,9 +144,9 @@ TRUNCATE(AVG(salary),2):d| AVG(salary):d | COUNT(1):l
; ;
groupByAndOrderByRoundWithPositiveParameter groupByAndOrderByRoundWithPositiveParameter
SELECT ROUND(AVG(salary), 2), AVG(salary), COUNT(*) FROM test_emp GROUP BY ROUND(salary, 2) ORDER BY ROUND(salary, 2) DESC LIMIT 10; SELECT ROUND(AVG(salary),2), AVG(salary), COUNT(*) FROM test_emp GROUP BY ROUND(salary, 2) ORDER BY ROUND(salary, 2) DESC LIMIT 10;
ROUND(AVG(salary),2):d| AVG(salary):d | COUNT(1):l ROUND(AVG(salary),2):d| AVG(salary):d | COUNT(*):l
----------------------+---------------+--------------- ----------------------+---------------+---------------
74999.0 |74999.0 |1 74999.0 |74999.0 |1
74970.0 |74970.0 |1 74970.0 |74970.0 |1
@ -163,16 +163,16 @@ ROUND(AVG(salary),2):d| AVG(salary):d | COUNT(1):l
groupByAndOrderByRoundWithNoSecondParameter groupByAndOrderByRoundWithNoSecondParameter
SELECT ROUND(AVG(salary)), ROUND(salary) rounded, AVG(salary), COUNT(*) FROM test_emp GROUP BY rounded ORDER BY rounded DESC LIMIT 10; SELECT ROUND(AVG(salary)), ROUND(salary) rounded, AVG(salary), COUNT(*) FROM test_emp GROUP BY rounded ORDER BY rounded DESC LIMIT 10;
ROUND(AVG(salary),0):d| rounded:i | AVG(salary):d | COUNT(1):l ROUND(AVG(salary)):d| rounded:i | AVG(salary):d | COUNT(*):l
----------------------+---------------+---------------+--------------- --------------------+---------------+---------------+---------------
74999.0 |74999 |74999.0 |1 74999.0 |74999 |74999.0 |1
74970.0 |74970 |74970.0 |1 74970.0 |74970 |74970.0 |1
74572.0 |74572 |74572.0 |1 74572.0 |74572 |74572.0 |1
73851.0 |73851 |73851.0 |1 73851.0 |73851 |73851.0 |1
73717.0 |73717 |73717.0 |1 73717.0 |73717 |73717.0 |1
73578.0 |73578 |73578.0 |1 73578.0 |73578 |73578.0 |1
71165.0 |71165 |71165.0 |1 71165.0 |71165 |71165.0 |1
70011.0 |70011 |70011.0 |1 70011.0 |70011 |70011.0 |1
69904.0 |69904 |69904.0 |1 69904.0 |69904 |69904.0 |1
68547.0 |68547 |68547.0 |1 68547.0 |68547 |68547.0 |1
; ;

View File

@ -5,39 +5,39 @@
equalsSelectClause equalsSelectClause
SELECT CAST(4 = 4 AS STRING), CAST(NOT 4 = 4 AS STRING), CAST(3 = 4 AS STRING), CAST(NOT 3 = 4 AS STRING), CAST(1 = null AS STRING), CAST(NOT null = 1 AS STRING); SELECT CAST(4 = 4 AS STRING), CAST(NOT 4 = 4 AS STRING), CAST(3 = 4 AS STRING), CAST(NOT 3 = 4 AS STRING), CAST(1 = null AS STRING), CAST(NOT null = 1 AS STRING);
CAST(4 == 4 AS VARCHAR):s | CAST(NOT(4 == 4) AS VARCHAR):s | CAST(3 == 4 AS VARCHAR):s | CAST(NOT(3 == 4) AS VARCHAR):s | CAST(1 == null AS VARCHAR):s | CAST(NOT(null == 1) AS VARCHAR):s CAST(4 = 4 AS STRING):s|CAST(NOT 4 = 4 AS STRING):s|CAST(3 = 4 AS STRING):s|CAST(NOT 3 = 4 AS STRING):s|CAST(1 = null AS STRING):s|CAST(NOT null = 1 AS STRING):s
----------------------------+---------------------------------+----------------------------+---------------------------------+-------------------------------+----------------------------------- -----------------------+---------------------------+-----------------------+---------------------------+--------------------------+----------------------------
true |false |false |true |null |null true |false |false |true |null |null
; ;
notEqualsSelectClause notEqualsSelectClause
SELECT CAST(4 != 4 AS STRING), CAST(NOT 4 != 4 AS STRING), CAST(3 != 4 AS STRING), CAST(NOT 3 != 4 AS STRING), CAST(1 != null AS STRING), CAST(NOT 1 != null AS STRING); SELECT CAST(4 != 4 AS STRING), CAST(NOT 4 != 4 AS STRING), CAST(3 != 4 AS STRING), CAST(NOT 3 != 4 AS STRING), CAST(1 != null AS STRING), CAST(NOT 1 != null AS STRING);
CAST(4 != 4 AS VARCHAR):s | CAST(NOT(4 != 4) AS VARCHAR):s | CAST(3 != 4 AS VARCHAR):s | CAST(NOT(3 != 4) AS VARCHAR):s | CAST(1 != null AS VARCHAR):s | CAST(NOT(1 != null) AS VARCHAR):s CAST(4 != 4 AS STRING):s|CAST(NOT 4 != 4 AS STRING):s|CAST(3 != 4 AS STRING):s|CAST(NOT 3 != 4 AS STRING):s|CAST(1 != null AS STRING):s|CAST(NOT 1 != null AS STRING):s
----------------------------+---------------------------------+----------------------------+---------------------------------+-------------------------------+----------------------------------- ------------------------+----------------------------+------------------------+----------------------------+---------------------------+-------------------------------
false |true |true |false |null |null false |true |true |false |null |null
; ;
equalSelectClauseWithTableColumns equalSelectClauseWithTableColumns
SELECT CAST(languages = 2 AS STRING), CAST(NOT languages = 2 AS STRING), CAST(languages = null AS STRING), CAST(NOT languages = null AS STRING) SELECT CAST(languages = 2 AS STRING), CAST(NOT languages = 2 AS STRING), CAST(languages = null AS STRING), CAST(NOT languages = null AS STRING)
FROM "test_emp" WHERE emp_no IN(10018, 10019, 10020) ORDER BY emp_no; FROM "test_emp" WHERE emp_no IN(10018, 10019, 10020) ORDER BY emp_no;
CAST((languages) == 2 AS VARCHAR):s | CAST(NOT((languages) == 2) AS VARCHAR):s | CAST((languages) == null AS VARCHAR):s | CAST(NOT((languages) == null) AS VARCHAR):s CAST(languages = 2 AS STRING):s|CAST(NOT languages = 2 AS STRING):s|CAST(languages = null AS STRING):s|CAST(NOT languages = null AS STRING):s
--------------------------------------+-------------------------------------------+-----------------------------------------+--------------------------------------------- -------------------------------+-----------------------------------+----------------------------------+--------------------------------------
true |false |null |null true |false |null |null
false |true |null |null false |true |null |null
null |null |null |null null |null |null |null
; ;
notEqualsAndNotEqualsSelectClauseWithTableColumns notEqualsAndNotEqualsSelectClauseWithTableColumns
SELECT CAST(languages != 2 AS STRING), CAST(NOT languages != 2 AS STRING), CAST(languages != null AS STRING), CAST(NOT languages != null AS STRING) SELECT CAST(languages != 2 AS STRING), CAST(NOT languages != 2 AS STRING), CAST(languages != null AS STRING), CAST(NOT languages != null AS STRING)
FROM "test_emp" WHERE emp_no IN(10018, 10019, 10020) ORDER BY emp_no; FROM "test_emp" WHERE emp_no IN(10018, 10019, 10020) ORDER BY emp_no;
CAST((languages) != 2 AS VARCHAR):s | CAST(NOT((languages) != 2) AS VARCHAR):s | CAST((languages) != null AS VARCHAR):s | CAST(NOT((languages) != null) AS VARCHAR):s CAST(languages != 2 AS STRING):s|CAST(NOT languages != 2 AS STRING):s|CAST(languages != null AS STRING):s|CAST(NOT languages != null AS STRING):s
--------------------------------------+-------------------------------------------+-----------------------------------------+--------------------------------------------- --------------------------------+------------------------------------+-----------------------------------+---------------------------------------
false |true |null |null false |true |null |null
true |false |null |null true |false |null |null
null |null |null |null null |null |null |null
; ;
@ -48,27 +48,27 @@ null |null
selectWithOrAndNullHandling selectWithOrAndNullHandling
SELECT CAST(true OR null AS STRING), CAST(null OR true AS STRING), CAST(false OR null AS STRING), CAST(null OR false AS STRING), CAST(null OR null AS STRING); SELECT CAST(true OR null AS STRING), CAST(null OR true AS STRING), CAST(false OR null AS STRING), CAST(null OR false AS STRING), CAST(null OR null AS STRING);
CAST(true OR null AS VARCHAR):s | CAST(null OR true AS VARCHAR):s | CAST(false OR null AS VARCHAR):s | CAST(null OR false AS VARCHAR):s | CAST(null OR null AS VARCHAR):s CAST(true OR null AS STRING):s|CAST(null OR true AS STRING):s|CAST(false OR null AS STRING):s|CAST(null OR false AS STRING):s|CAST(null OR null AS STRING):s
----------------------------------+----------------------------------+-----------------------------------+-----------------------------------+--------------------------------- ------------------------------+------------------------------+-------------------------------+-------------------------------+----------------------------
true |true |null |null |null true |true |null |null |null
; ;
selectWithAndAndNullHandling selectWithAndAndNullHandling
SELECT CAST(true AND null AS STRING), CAST(null AND true AS STRING), CAST(false AND null AS STRING), CAST(null AND false AS STRING), CAST(null AND null AS STRING); SELECT CAST(true AND null AS STRING), CAST(null AND true AS STRING), CAST(false AND null AS STRING), CAST(null AND false AS STRING), CAST(null AND null AS STRING);
CAST(true AND null AS VARCHAR):s | CAST(null AND true AS VARCHAR):s | CAST(false AND null AS VARCHAR):s | CAST(null AND false AS VARCHAR):s | CAST(null AND null AS VARCHAR):s CAST(true AND null AS STRING):s|CAST(null AND true AS STRING):s|CAST(false AND null AS STRING):s|CAST(null AND false AS STRING):s|CAST(null AND null AS STRING):s
-----------------------------------+-----------------------------------+------------------------------------+------------------------------------+---------------------------------- -------------------------------+-------------------------------+--------------------------------+--------------------------------+-----------------------------
null |null |false |false |null null |null |false |false |null
; ;
selectWithOrAndAndAndNullHandling_WithTableColumns selectWithOrAndAndAndNullHandling_WithTableColumns
SELECT CAST(languages = 2 OR null AS STRING), CAST(languages = 2 AND null AS STRING) FROM test_emp WHERE emp_no BETWEEN 10018 AND 10020 ORDER BY emp_no; SELECT CAST(languages = 2 OR null AS STRING), CAST(languages = 2 AND null AS STRING) FROM test_emp WHERE emp_no BETWEEN 10018 AND 10020 ORDER BY emp_no;
CAST(((languages) == 2) OR null AS VARCHAR):s | CAST(((languages) == 2) AND null AS VARCHAR):s CAST(languages = 2 OR null AS STRING):s|CAST(languages = 2 AND null AS STRING):s
-----------------------------------------------+------------------------------------------------ ---------------------------------------+----------------------------------------
true |null true |null
null |false null |false
null |null null |null
; ;
@ -76,45 +76,45 @@ null |null
// SELECT with IN // SELECT with IN
// //
inWithLiterals inWithLiterals
SELECT 1 IN (1, 2, 3), 1 IN (2, 3); SELECT 1 IN (1,2, 3), 1 IN (2, 3);
1 IN (1, 2, 3):b | 1 IN (2, 3):b 1 IN (1,2, 3) | 1 IN (2, 3)
-------------------+------------- ---------------+---------------
true |false true |false
; ;
inWithLiteralsAndFunctions inWithLiteralsAndFunctions
SELECT 1 IN (2 - 1, 2, 3), abs(-1) IN (2, 3, abs(4 - 5)); SELECT 1 IN (2 - 1, 2, 3), abs(-1) IN (2, 3, abs(4 - 5));
1 IN (2 - 1, 2, 3) | ABS(-1) IN (2, 3, ABS(4 - 5)) 1 IN (2 - 1, 2, 3)|abs(-1) IN (2, 3, abs(4 - 5))
---------------------+------------------------------ ------------------+-----------------------------
true |true true |true
; ;
inWithLiteralsAndNegation inWithLiteralsAndNegation
SELECT 1 NOT IN (1, 1 + 1, 3), 1 NOT IN (2, 3); SELECT 1 NOT IN (1, 1 + 1, 3), 1 NOT IN (2, 3);
NOT(1 IN (1, 1 + 1, 3)) | NOT(1 IN (2, 3)) 1 NOT IN (1, 1 + 1, 3)|1 NOT IN (2, 3)
--------------------------+----------------- ----------------------+---------------
false |true false |true
; ;
// Need to CAST as STRING since for boolean types the jdbc CSV translates null -> false // Need to CAST as STRING since for boolean types the jdbc CSV translates null -> false
inWithNullHandling inWithNullHandling
SELECT CAST(2 IN (1, null, 3) AS STRING), CAST(3 IN (1, null, 3) AS STRING), CAST(null IN (1, null, 3) AS STRING), CAST(null IN (1, 2, 3) AS STRING); SELECT CAST(2 IN (1, null, 3) AS STRING), CAST(3 IN (1, null, 3) AS STRING), CAST(null IN (1, null, 3) AS STRING), CAST(null IN (1, 2, 3) AS STRING);
CAST(2 IN (1, null, 3) AS VARCHAR):s | CAST(3 IN (1, null, 3) AS VARCHAR):s | CAST(null IN (1, null, 3) AS VARCHAR):s | CAST(null IN (1, 2, 3) AS VARCHAR):s CAST(2 IN (1, null, 3) AS STRING):s|CAST(3 IN (1, null, 3) AS STRING):s|CAST(null IN (1, null, 3) AS STRING):s|CAST(null IN (1, 2, 3) AS STRING):s
---------------------------------------+--------------------------------------+------------------------------------------+-------------------------------------- -----------------------------------+-----------------------------------+--------------------------------------+-----------------------------------
null |true |null |null null |true |null |null
; ;
inWithNullHandlingAndNegation inWithNullHandlingAndNegation
SELECT CAST(NOT 2 IN (1, null, 3) AS STRING), CAST(3 NOT IN (1, null, 3) AS STRING), CAST(NOT null IN (1, null, 3) AS STRING), CAST(null NOT IN (1, 2, 3) AS STRING); SELECT CAST(NOT 2 IN (1, null, 3) AS STRING), CAST(3 NOT IN (1, null, 3) AS STRING), CAST(NOT null IN (1, null, 3) AS STRING), CAST(null NOT IN (1, 2, 3) AS STRING);
CAST(NOT(2 IN (1, null, 3)) AS VARCHAR):s | CAST(NOT(3 IN (1, null, 3)) AS VARCHAR):s | CAST(NOT(null IN (1, null, 3)) AS VARCHAR):s | CAST(NOT(null IN (1, 2, 3)) AS VARCHAR):s CAST(NOT 2 IN (1, null, 3) AS STRING):s|CAST(3 NOT IN (1, null, 3) AS STRING):s|CAST(NOT null IN (1, null, 3) AS STRING):s|CAST(null NOT IN (1, 2, 3) AS STRING):s
--------------------------------------------+--------------------------------------------+-----------------------------------------------+------------------------------------------- ---------------------------------------+---------------------------------------+------------------------------------------+---------------------------------------
null |false |null |null null |false |null |null
; ;
// //
@ -134,34 +134,34 @@ false
inWithTableColumnAndFunction inWithTableColumnAndFunction
SELECT emp_no IN (10000, 10000 + 1, abs(-10000 - 2)) FROM test_emp WHERE emp_no BETWEEN 10001 AND 10004 ORDER BY emp_no; SELECT emp_no IN (10000, 10000 + 1, abs(-10000 - 2)) FROM test_emp WHERE emp_no BETWEEN 10001 AND 10004 ORDER BY emp_no;
emp_no IN (10000, 10000 + 1, ABS(-10000 - 2)):b emp_no IN (10000, 10000 + 1, abs(-10000 - 2))
------------------------------------------------ ---------------------------------------------
true true
true true
false false
false false
; ;
inWithTableColumnAndNegation inWithTableColumnAndNegation
SELECT emp_no NOT IN (10000, 10000 + 1, 10002) FROM test_emp WHERE emp_no BETWEEN 10001 AND 10004 ORDER BY emp_no; SELECT emp_no NOT IN (10000, 10000 + 1, 10002) FROM test_emp WHERE emp_no BETWEEN 10001 AND 10004 ORDER BY emp_no;
NOT(emp_no IN (10000, 10000 + 1, 10002)):b emp_no NOT IN (10000, 10000 + 1, 10002)
------------------------------------------- ---------------------------------------
false false
false false
true true
true true
; ;
inWithTableColumnAndComplexFunctions inWithTableColumnAndComplexFunctions
SELECT emp_no IN (1, abs(1 - 10002), 3) OR emp_no NOT IN (10000, 10000 + 2, 10003) FROM test_emp WHERE emp_no BETWEEN 10001 AND 10004 ORDER BY emp_no; SELECT emp_no IN (1, abs(1 - 10002), 3) OR emp_no NOT IN (10000, 10000 + 2, 10003) FROM test_emp WHERE emp_no BETWEEN 10001 AND 10004 ORDER BY emp_no;
(emp_no IN (1, ABS(1 - 10002), 3)) OR (NOT(emp_no IN (10000, 10000 + 2, 10003))):b emp_no IN (1, abs(1 - 10002), 3) OR emp_no NOT IN (10000, 10000 + 2, 10003)
---------------------------------------------------------------------------------- ---------------------------------------------------------------------------
true true
false false
false false
true true
; ;
@ -169,19 +169,19 @@ true
inWithTableColumnAndNullHandling inWithTableColumnAndNullHandling
SELECT emp_no, CAST(languages IN (2, 3) AS STRING), CAST(languages IN (2, null, 3) AS STRING) FROM test_emp WHERE emp_no BETWEEN 10018 AND 10020 ORDER BY emp_no; SELECT emp_no, CAST(languages IN (2, 3) AS STRING), CAST(languages IN (2, null, 3) AS STRING) FROM test_emp WHERE emp_no BETWEEN 10018 AND 10020 ORDER BY emp_no;
emp_no:i | CAST(languages IN (2, 3) AS VARCHAR):s | CAST(languages IN (2, null, 3) AS VARCHAR):s emp_no:i |CAST(languages IN (2, 3) AS STRING):s|CAST(languages IN (2, null, 3) AS STRING):s
----------+-----------------------------------------+---------------------------------------------- ---------------+-------------------------------------+-------------------------------------------
10018 |true |true 10018 |true |true
10019 |false |null 10019 |false |null
10020 |null |null 10020 |null |null
; ;
inWithTableColumnAndNullHandlingAndNegation inWithTableColumnAndNullHandlingAndNegation
SELECT emp_no, CAST(languages NOT IN (2, 3) AS STRING), CAST(NOT languages IN (2, null, 3) AS STRING) FROM test_emp WHERE emp_no BETWEEN 10018 AND 10020 ORDER BY emp_no; SELECT emp_no, CAST(languages NOT IN (2, 3) AS STRING), CAST(NOT languages IN (2, null, 3) AS STRING) FROM test_emp WHERE emp_no BETWEEN 10018 AND 10020 ORDER BY emp_no;
emp_no:i | CAST(NOT(languages IN (2, 3)) AS VARCHAR):s | CAST(NOT(languages IN (2, null, 3)) AS VARCHAR):s emp_no:i |CAST(languages NOT IN (2, 3) AS STRING):s|CAST(NOT languages IN (2, null, 3) AS STRING):s
----------+----------------------------------------------+--------------------------------------------------- ---------------+-----------------------------------------+-----------------------------------------------
10018 |false |false 10018 |false |false
10019 |true |null 10019 |true |null
10020 |null |null 10020 |null |null
; ;

View File

@ -772,7 +772,7 @@ public class Analyzer extends RuleExecutor<LogicalPlan> {
for (Function seenFunction : list) { for (Function seenFunction : list) {
if (seenFunction != f && f.arguments().equals(seenFunction.arguments())) { if (seenFunction != f && f.arguments().equals(seenFunction.arguments())) {
// Special check for COUNT: an already seen COUNT function will be returned only if its DISTINCT property // Special check for COUNT: an already seen COUNT function will be returned only if its DISTINCT property
// matches the one from the unresolved function to be checked. // matches the one from the unresolved function to be checked.
if (seenFunction instanceof Count) { if (seenFunction instanceof Count) {
if (seenFunction.equals(f)){ if (seenFunction.equals(f)){
return seenFunction; return seenFunction;
@ -818,7 +818,7 @@ public class Analyzer extends RuleExecutor<LogicalPlan> {
for (Function seenFunction : list) { for (Function seenFunction : list) {
if (uf.arguments().equals(seenFunction.arguments())) { if (uf.arguments().equals(seenFunction.arguments())) {
// Special check for COUNT: an already seen COUNT function will be returned only if its DISTINCT property // Special check for COUNT: an already seen COUNT function will be returned only if its DISTINCT property
// matches the one from the unresolved function to be checked. // matches the one from the unresolved function to be checked.
if (seenFunction instanceof Count) { if (seenFunction instanceof Count) {
if (uf.sameAs((Count) seenFunction)) { if (uf.sameAs((Count) seenFunction)) {
return seenFunction; return seenFunction;
@ -899,8 +899,7 @@ public class Analyzer extends RuleExecutor<LogicalPlan> {
return new Alias(c.source(), ((NamedExpression) c.field()).name(), c); return new Alias(c.source(), ((NamedExpression) c.field()).name(), c);
} }
} }
//TODO: maybe add something closer to SQL return new Alias(child.source(), child.sourceText(), child);
return new Alias(child.source(), child.toString(), child);
}, UnresolvedAlias.class); }, UnresolvedAlias.class);
newExpr.add(expr.equals(transformed) ? expr : transformed); newExpr.add(expr.equals(transformed) ? expr : transformed);
} }
@ -1031,7 +1030,7 @@ public class Analyzer extends RuleExecutor<LogicalPlan> {
} }
private boolean functionsEquals(Function f, Function seenFunction) { private boolean functionsEquals(Function f, Function seenFunction) {
return f.name().equals(seenFunction.name()) && f.arguments().equals(seenFunction.arguments()); return f.sourceText().equals(seenFunction.sourceText()) && f.arguments().equals(seenFunction.arguments());
} }
} }

View File

@ -36,7 +36,7 @@ public class Literal extends NamedExpression {
} }
public Literal(Source source, String name, Object value, DataType dataType) { public Literal(Source source, String name, Object value, DataType dataType) {
super(source, name == null ? String.valueOf(value) : name, emptyList(), null); super(source, name == null ? source.text() : name, emptyList(), null);
this.dataType = dataType; this.dataType = dataType;
this.value = DataTypeConversion.convert(value, dataType); this.value = DataTypeConversion.convert(value, dataType);
} }

View File

@ -14,7 +14,6 @@ import org.elasticsearch.xpack.sql.tree.Source;
import org.elasticsearch.xpack.sql.util.StringUtils; import org.elasticsearch.xpack.sql.util.StringUtils;
import java.util.List; import java.util.List;
import java.util.StringJoiner;
/** /**
* Any SQL expression with parentheses, like {@code MAX()}, or {@code ABS()}. A * Any SQL expression with parentheses, like {@code MAX()}, or {@code ABS()}. A
@ -33,7 +32,7 @@ public abstract class Function extends NamedExpression {
// cannot detect name yet so override the name // cannot detect name yet so override the name
super(source, null, children, id, synthetic); super(source, null, children, id, synthetic);
functionName = StringUtils.camelCaseToUnderscore(getClass().getSimpleName()); functionName = StringUtils.camelCaseToUnderscore(getClass().getSimpleName());
name = functionName() + functionArgs(); name = source.text();
} }
public final List<Expression> arguments() { public final List<Expression> arguments() {
@ -52,7 +51,7 @@ public abstract class Function extends NamedExpression {
@Override @Override
public String toString() { public String toString() {
return name() + "#" + id(); return sourceText() + "#" + id();
} }
public String functionName() { public String functionName() {
@ -64,16 +63,7 @@ public abstract class Function extends NamedExpression {
return id().toString(); return id().toString();
} }
protected String functionArgs() {
StringJoiner sj = new StringJoiner(",", "(", ")");
for (Expression child : children()) {
String val = child instanceof NamedExpression && child.resolved() ? Expressions.name(child) : child.toString();
sj.add(val);
}
return sj.toString();
}
public boolean functionEquals(Function f) { public boolean functionEquals(Function f) {
return f != null && getClass() == f.getClass() && arguments().equals(f.arguments()); return f != null && getClass() == f.getClass() && arguments().equals(f.arguments());
} }
} }

View File

@ -166,7 +166,7 @@ public class UnresolvedFunction extends Function implements Unresolvable {
@Override @Override
public String toString() { public String toString() {
return UNRESOLVED_PREFIX + functionName() + functionArgs(); return UNRESOLVED_PREFIX + sourceText();
} }
@Override @Override

View File

@ -8,8 +8,8 @@ package org.elasticsearch.xpack.sql.expression.function.aggregate;
import org.elasticsearch.xpack.sql.expression.Expression; import org.elasticsearch.xpack.sql.expression.Expression;
import org.elasticsearch.xpack.sql.expression.Expressions; import org.elasticsearch.xpack.sql.expression.Expressions;
import org.elasticsearch.xpack.sql.expression.Expressions.ParamOrdinal; import org.elasticsearch.xpack.sql.expression.Expressions.ParamOrdinal;
import org.elasticsearch.xpack.sql.tree.Source;
import org.elasticsearch.xpack.sql.tree.NodeInfo; import org.elasticsearch.xpack.sql.tree.NodeInfo;
import org.elasticsearch.xpack.sql.tree.Source;
import org.elasticsearch.xpack.sql.type.DataType; import org.elasticsearch.xpack.sql.type.DataType;
import java.util.List; import java.util.List;
@ -45,6 +45,6 @@ public class Max extends NumericAggregate implements EnclosedAgg {
@Override @Override
protected TypeResolution resolveType() { protected TypeResolution resolveType() {
return Expressions.typeMustBeNumericOrDate(field(), functionName(), ParamOrdinal.DEFAULT); return Expressions.typeMustBeNumericOrDate(field(), sourceText(), ParamOrdinal.DEFAULT);
} }
} }

View File

@ -8,8 +8,8 @@ package org.elasticsearch.xpack.sql.expression.function.aggregate;
import org.elasticsearch.xpack.sql.expression.Expression; import org.elasticsearch.xpack.sql.expression.Expression;
import org.elasticsearch.xpack.sql.expression.Expressions; import org.elasticsearch.xpack.sql.expression.Expressions;
import org.elasticsearch.xpack.sql.expression.Expressions.ParamOrdinal; import org.elasticsearch.xpack.sql.expression.Expressions.ParamOrdinal;
import org.elasticsearch.xpack.sql.tree.Source;
import org.elasticsearch.xpack.sql.tree.NodeInfo; import org.elasticsearch.xpack.sql.tree.NodeInfo;
import org.elasticsearch.xpack.sql.tree.Source;
import org.elasticsearch.xpack.sql.type.DataType; import org.elasticsearch.xpack.sql.type.DataType;
import java.util.List; import java.util.List;
@ -48,6 +48,6 @@ public class Min extends NumericAggregate implements EnclosedAgg {
@Override @Override
protected TypeResolution resolveType() { protected TypeResolution resolveType() {
return Expressions.typeMustBeNumericOrDate(field(), functionName(), ParamOrdinal.DEFAULT); return Expressions.typeMustBeNumericOrDate(field(), sourceText(), ParamOrdinal.DEFAULT);
} }
} }

View File

@ -25,7 +25,7 @@ abstract class NumericAggregate extends AggregateFunction {
@Override @Override
protected TypeResolution resolveType() { protected TypeResolution resolveType() {
return Expressions.typeMustBeNumeric(field(), functionName(), ParamOrdinal.DEFAULT); return Expressions.typeMustBeNumeric(field(), sourceText(), ParamOrdinal.DEFAULT);
} }
@Override @Override

View File

@ -10,8 +10,8 @@ import org.elasticsearch.xpack.sql.expression.Expression;
import org.elasticsearch.xpack.sql.expression.Expressions; import org.elasticsearch.xpack.sql.expression.Expressions;
import org.elasticsearch.xpack.sql.expression.Expressions.ParamOrdinal; import org.elasticsearch.xpack.sql.expression.Expressions.ParamOrdinal;
import org.elasticsearch.xpack.sql.expression.Foldables; import org.elasticsearch.xpack.sql.expression.Foldables;
import org.elasticsearch.xpack.sql.tree.Source;
import org.elasticsearch.xpack.sql.tree.NodeInfo; import org.elasticsearch.xpack.sql.tree.NodeInfo;
import org.elasticsearch.xpack.sql.tree.Source;
import org.elasticsearch.xpack.sql.type.DataType; import org.elasticsearch.xpack.sql.type.DataType;
import java.util.List; import java.util.List;
@ -52,7 +52,7 @@ public class Percentile extends NumericAggregate implements EnclosedAgg {
return resolution; return resolution;
} }
return Expressions.typeMustBeNumeric(percent, functionName(), ParamOrdinal.DEFAULT); return Expressions.typeMustBeNumeric(percent, sourceText(), ParamOrdinal.DEFAULT);
} }
public Expression percent() { public Expression percent() {

View File

@ -10,8 +10,8 @@ import org.elasticsearch.xpack.sql.expression.Expression;
import org.elasticsearch.xpack.sql.expression.Expressions; import org.elasticsearch.xpack.sql.expression.Expressions;
import org.elasticsearch.xpack.sql.expression.Expressions.ParamOrdinal; import org.elasticsearch.xpack.sql.expression.Expressions.ParamOrdinal;
import org.elasticsearch.xpack.sql.expression.Foldables; import org.elasticsearch.xpack.sql.expression.Foldables;
import org.elasticsearch.xpack.sql.tree.Source;
import org.elasticsearch.xpack.sql.tree.NodeInfo; import org.elasticsearch.xpack.sql.tree.NodeInfo;
import org.elasticsearch.xpack.sql.tree.Source;
import org.elasticsearch.xpack.sql.type.DataType; import org.elasticsearch.xpack.sql.type.DataType;
import java.util.List; import java.util.List;
@ -52,7 +52,7 @@ public class PercentileRank extends AggregateFunction implements EnclosedAgg {
return resolution; return resolution;
} }
return Expressions.typeMustBeNumeric(value, functionName(), ParamOrdinal.DEFAULT); return Expressions.typeMustBeNumeric(value, sourceText(), ParamOrdinal.DEFAULT);
} }
public Expression value() { public Expression value() {

View File

@ -111,16 +111,4 @@ public class Cast extends UnaryScalarFunction {
return Objects.equals(dataType, other.dataType()) return Objects.equals(dataType, other.dataType())
&& Objects.equals(field(), other.field()); && Objects.equals(field(), other.field());
} }
@Override
public String toString() {
return functionName() + "(" + field().toString() + " AS " + to().sqlName() + ")#" + id();
}
@Override
public String name() {
StringBuilder sb = new StringBuilder(super.name());
sb.insert(sb.length() - 1, " AS " + to().sqlName());
return sb.toString();
}
} }

View File

@ -12,7 +12,6 @@ import org.elasticsearch.xpack.sql.expression.gen.script.ScriptTemplate;
import org.elasticsearch.xpack.sql.session.Configuration; import org.elasticsearch.xpack.sql.session.Configuration;
import org.elasticsearch.xpack.sql.tree.Source; import org.elasticsearch.xpack.sql.tree.Source;
import org.elasticsearch.xpack.sql.type.DataType; import org.elasticsearch.xpack.sql.type.DataType;
import org.elasticsearch.xpack.sql.util.StringUtils;
import java.util.List; import java.util.List;
import java.util.Objects; import java.util.Objects;
@ -55,11 +54,6 @@ public abstract class ConfigurationFunction extends ScalarFunction {
@Override @Override
public abstract Object fold(); public abstract Object fold();
@Override
protected String functionArgs() {
return StringUtils.EMPTY;
}
@Override @Override
public ScriptTemplate asScript() { public ScriptTemplate asScript() {
return asScript(this); return asScript(this);

View File

@ -10,8 +10,8 @@ import org.elasticsearch.xpack.sql.expression.Expression;
import org.elasticsearch.xpack.sql.expression.Expressions; import org.elasticsearch.xpack.sql.expression.Expressions;
import org.elasticsearch.xpack.sql.expression.Expressions.ParamOrdinal; import org.elasticsearch.xpack.sql.expression.Expressions.ParamOrdinal;
import org.elasticsearch.xpack.sql.expression.function.scalar.UnaryScalarFunction; import org.elasticsearch.xpack.sql.expression.function.scalar.UnaryScalarFunction;
import org.elasticsearch.xpack.sql.tree.Source;
import org.elasticsearch.xpack.sql.tree.NodeInfo; import org.elasticsearch.xpack.sql.tree.NodeInfo;
import org.elasticsearch.xpack.sql.tree.Source;
import java.time.ZoneId; import java.time.ZoneId;
import java.time.ZonedDateTime; import java.time.ZonedDateTime;
@ -20,17 +20,10 @@ import java.util.Objects;
abstract class BaseDateTimeFunction extends UnaryScalarFunction { abstract class BaseDateTimeFunction extends UnaryScalarFunction {
private final ZoneId zoneId; private final ZoneId zoneId;
private final String name;
BaseDateTimeFunction(Source source, Expression field, ZoneId zoneId) { BaseDateTimeFunction(Source source, Expression field, ZoneId zoneId) {
super(source, field); super(source, field);
this.zoneId = zoneId; this.zoneId = zoneId;
StringBuilder sb = new StringBuilder(super.name());
// add timezone as last argument
sb.insert(sb.length() - 1, " [" + zoneId.getId() + "]");
this.name = sb.toString();
} }
@Override @Override
@ -42,17 +35,12 @@ abstract class BaseDateTimeFunction extends UnaryScalarFunction {
@Override @Override
protected TypeResolution resolveType() { protected TypeResolution resolveType() {
return Expressions.typeMustBeDate(field(), functionName(), ParamOrdinal.DEFAULT); return Expressions.typeMustBeDate(field(), sourceText(), ParamOrdinal.DEFAULT);
} }
public ZoneId zoneId() { public ZoneId zoneId() {
return zoneId; return zoneId;
} }
@Override
public String name() {
return name;
}
@Override @Override
public boolean foldable() { public boolean foldable() {

View File

@ -36,12 +36,12 @@ public abstract class BinaryNumericFunction extends BinaryScalarFunction {
return new TypeResolution("Unresolved children"); return new TypeResolution("Unresolved children");
} }
TypeResolution resolution = Expressions.typeMustBeNumeric(left(), functionName(), ParamOrdinal.FIRST); TypeResolution resolution = Expressions.typeMustBeNumeric(left(), sourceText(), ParamOrdinal.FIRST);
if (resolution.unresolved()) { if (resolution.unresolved()) {
return resolution; return resolution;
} }
return Expressions.typeMustBeNumeric(right(), functionName(), ParamOrdinal.SECOND); return Expressions.typeMustBeNumeric(right(), sourceText(), ParamOrdinal.SECOND);
} }
@Override @Override

View File

@ -11,10 +11,9 @@ import org.elasticsearch.xpack.sql.expression.Literal;
import org.elasticsearch.xpack.sql.expression.function.scalar.math.MathProcessor.MathOperation; import org.elasticsearch.xpack.sql.expression.function.scalar.math.MathProcessor.MathOperation;
import org.elasticsearch.xpack.sql.expression.gen.script.Params; import org.elasticsearch.xpack.sql.expression.gen.script.Params;
import org.elasticsearch.xpack.sql.expression.gen.script.ScriptTemplate; import org.elasticsearch.xpack.sql.expression.gen.script.ScriptTemplate;
import org.elasticsearch.xpack.sql.tree.Source;
import org.elasticsearch.xpack.sql.tree.NodeInfo; import org.elasticsearch.xpack.sql.tree.NodeInfo;
import org.elasticsearch.xpack.sql.tree.Source;
import org.elasticsearch.xpack.sql.type.DataType; import org.elasticsearch.xpack.sql.type.DataType;
import org.elasticsearch.xpack.sql.util.StringUtils;
public class E extends MathFunction { public class E extends MathFunction {
@ -39,11 +38,6 @@ public class E extends MathFunction {
return Math.E; return Math.E;
} }
@Override
protected String functionArgs() {
return StringUtils.EMPTY;
}
@Override @Override
public ScriptTemplate asScript() { public ScriptTemplate asScript() {
return TEMPLATE; return TEMPLATE;

View File

@ -11,10 +11,9 @@ import org.elasticsearch.xpack.sql.expression.Literal;
import org.elasticsearch.xpack.sql.expression.function.scalar.math.MathProcessor.MathOperation; import org.elasticsearch.xpack.sql.expression.function.scalar.math.MathProcessor.MathOperation;
import org.elasticsearch.xpack.sql.expression.gen.script.Params; import org.elasticsearch.xpack.sql.expression.gen.script.Params;
import org.elasticsearch.xpack.sql.expression.gen.script.ScriptTemplate; import org.elasticsearch.xpack.sql.expression.gen.script.ScriptTemplate;
import org.elasticsearch.xpack.sql.tree.Source;
import org.elasticsearch.xpack.sql.tree.NodeInfo; import org.elasticsearch.xpack.sql.tree.NodeInfo;
import org.elasticsearch.xpack.sql.tree.Source;
import org.elasticsearch.xpack.sql.type.DataType; import org.elasticsearch.xpack.sql.type.DataType;
import org.elasticsearch.xpack.sql.util.StringUtils;
public class Pi extends MathFunction { public class Pi extends MathFunction {
@ -39,11 +38,6 @@ public class Pi extends MathFunction {
return Math.PI; return Math.PI;
} }
@Override
protected String functionArgs() {
return StringUtils.EMPTY;
}
@Override @Override
public ScriptTemplate asScript() { public ScriptTemplate asScript() {
return TEMPLATE; return TEMPLATE;

View File

@ -6,6 +6,7 @@
package org.elasticsearch.xpack.sql.expression.function.scalar.string; package org.elasticsearch.xpack.sql.expression.function.scalar.string;
import org.elasticsearch.xpack.sql.expression.Expression; import org.elasticsearch.xpack.sql.expression.Expression;
import org.elasticsearch.xpack.sql.expression.Expressions.ParamOrdinal;
import org.elasticsearch.xpack.sql.expression.FieldAttribute; import org.elasticsearch.xpack.sql.expression.FieldAttribute;
import org.elasticsearch.xpack.sql.expression.function.scalar.BinaryScalarFunction; import org.elasticsearch.xpack.sql.expression.function.scalar.BinaryScalarFunction;
import org.elasticsearch.xpack.sql.expression.gen.script.ScriptTemplate; import org.elasticsearch.xpack.sql.expression.gen.script.ScriptTemplate;
@ -15,7 +16,6 @@ import java.util.Locale;
import java.util.Objects; import java.util.Objects;
import java.util.function.BiFunction; import java.util.function.BiFunction;
import static org.elasticsearch.xpack.sql.expression.Expressions.ParamOrdinal;
import static org.elasticsearch.xpack.sql.expression.Expressions.typeMustBeString; import static org.elasticsearch.xpack.sql.expression.Expressions.typeMustBeString;
import static org.elasticsearch.xpack.sql.expression.gen.script.ParamsBuilder.paramsBuilder; import static org.elasticsearch.xpack.sql.expression.gen.script.ParamsBuilder.paramsBuilder;
@ -42,7 +42,7 @@ public abstract class BinaryStringFunction<T,R> extends BinaryScalarFunction {
return new TypeResolution("Unresolved children"); return new TypeResolution("Unresolved children");
} }
TypeResolution resolution = typeMustBeString(left(), functionName(), ParamOrdinal.FIRST); TypeResolution resolution = typeMustBeString(left(), sourceText(), ParamOrdinal.FIRST);
if (resolution.unresolved()) { if (resolution.unresolved()) {
return resolution; return resolution;
} }

View File

@ -26,7 +26,7 @@ public abstract class BinaryStringNumericFunction extends BinaryStringFunction<N
@Override @Override
protected TypeResolution resolveSecondParameterInputType(Expression e) { protected TypeResolution resolveSecondParameterInputType(Expression e) {
return Expressions.typeMustBeNumeric(e,functionName(), Expressions.ParamOrdinal.SECOND); return Expressions.typeMustBeNumeric(e, sourceText(), Expressions.ParamOrdinal.SECOND);
} }
@Override @Override

View File

@ -21,7 +21,7 @@ public abstract class BinaryStringStringFunction extends BinaryStringFunction<St
@Override @Override
protected TypeResolution resolveSecondParameterInputType(Expression e) { protected TypeResolution resolveSecondParameterInputType(Expression e) {
return Expressions.typeMustBeString(e, functionName(), Expressions.ParamOrdinal.SECOND); return Expressions.typeMustBeString(e, sourceText(), Expressions.ParamOrdinal.SECOND);
} }
@Override @Override

View File

@ -13,8 +13,8 @@ import org.elasticsearch.xpack.sql.expression.Nullability;
import org.elasticsearch.xpack.sql.expression.function.scalar.BinaryScalarFunction; import org.elasticsearch.xpack.sql.expression.function.scalar.BinaryScalarFunction;
import org.elasticsearch.xpack.sql.expression.gen.pipeline.Pipe; import org.elasticsearch.xpack.sql.expression.gen.pipeline.Pipe;
import org.elasticsearch.xpack.sql.expression.gen.script.ScriptTemplate; import org.elasticsearch.xpack.sql.expression.gen.script.ScriptTemplate;
import org.elasticsearch.xpack.sql.tree.Source;
import org.elasticsearch.xpack.sql.tree.NodeInfo; import org.elasticsearch.xpack.sql.tree.NodeInfo;
import org.elasticsearch.xpack.sql.tree.Source;
import org.elasticsearch.xpack.sql.type.DataType; import org.elasticsearch.xpack.sql.type.DataType;
import static org.elasticsearch.xpack.sql.expression.function.scalar.string.ConcatFunctionProcessor.process; import static org.elasticsearch.xpack.sql.expression.function.scalar.string.ConcatFunctionProcessor.process;
@ -37,12 +37,12 @@ public class Concat extends BinaryScalarFunction {
return new TypeResolution("Unresolved children"); return new TypeResolution("Unresolved children");
} }
TypeResolution sourceResolution = Expressions.typeMustBeString(left(), functionName(), ParamOrdinal.FIRST); TypeResolution sourceResolution = Expressions.typeMustBeString(left(), sourceText(), ParamOrdinal.FIRST);
if (sourceResolution.unresolved()) { if (sourceResolution.unresolved()) {
return sourceResolution; return sourceResolution;
} }
return Expressions.typeMustBeString(right(), functionName(), ParamOrdinal.SECOND); return Expressions.typeMustBeString(right(), sourceText(), ParamOrdinal.SECOND);
} }
@Override @Override

View File

@ -46,22 +46,22 @@ public class Insert extends ScalarFunction {
return new TypeResolution("Unresolved children"); return new TypeResolution("Unresolved children");
} }
TypeResolution sourceResolution = Expressions.typeMustBeString(source, functionName(), ParamOrdinal.FIRST); TypeResolution sourceResolution = Expressions.typeMustBeString(source, sourceText(), ParamOrdinal.FIRST);
if (sourceResolution.unresolved()) { if (sourceResolution.unresolved()) {
return sourceResolution; return sourceResolution;
} }
TypeResolution startResolution = Expressions.typeMustBeNumeric(start, functionName(), ParamOrdinal.SECOND); TypeResolution startResolution = Expressions.typeMustBeNumeric(start, sourceText(), ParamOrdinal.SECOND);
if (startResolution.unresolved()) { if (startResolution.unresolved()) {
return startResolution; return startResolution;
} }
TypeResolution lengthResolution = Expressions.typeMustBeNumeric(length, functionName(), ParamOrdinal.THIRD); TypeResolution lengthResolution = Expressions.typeMustBeNumeric(length, sourceText(), ParamOrdinal.THIRD);
if (lengthResolution.unresolved()) { if (lengthResolution.unresolved()) {
return lengthResolution; return lengthResolution;
} }
return Expressions.typeMustBeString(replacement, functionName(), ParamOrdinal.FOURTH); return Expressions.typeMustBeString(replacement, sourceText(), ParamOrdinal.FOURTH);
} }
@Override @Override

View File

@ -48,19 +48,19 @@ public class Locate extends ScalarFunction {
return new TypeResolution("Unresolved children"); return new TypeResolution("Unresolved children");
} }
TypeResolution patternResolution = Expressions.typeMustBeString(pattern, functionName(), ParamOrdinal.FIRST); TypeResolution patternResolution = Expressions.typeMustBeString(pattern, sourceText(), ParamOrdinal.FIRST);
if (patternResolution.unresolved()) { if (patternResolution.unresolved()) {
return patternResolution; return patternResolution;
} }
TypeResolution sourceResolution = Expressions.typeMustBeString(source, functionName(), ParamOrdinal.SECOND); TypeResolution sourceResolution = Expressions.typeMustBeString(source, sourceText(), ParamOrdinal.SECOND);
if (sourceResolution.unresolved()) { if (sourceResolution.unresolved()) {
return sourceResolution; return sourceResolution;
} }
return start == null ? return start == null ?
TypeResolution.TYPE_RESOLVED : TypeResolution.TYPE_RESOLVED :
Expressions.typeMustBeNumeric(start, functionName(), ParamOrdinal.THIRD); Expressions.typeMustBeNumeric(start, sourceText(), ParamOrdinal.THIRD);
} }
@Override @Override

View File

@ -44,17 +44,17 @@ public class Replace extends ScalarFunction {
return new TypeResolution("Unresolved children"); return new TypeResolution("Unresolved children");
} }
TypeResolution sourceResolution = Expressions.typeMustBeString(source, functionName(), ParamOrdinal.FIRST); TypeResolution sourceResolution = Expressions.typeMustBeString(source, sourceText(), ParamOrdinal.FIRST);
if (sourceResolution.unresolved()) { if (sourceResolution.unresolved()) {
return sourceResolution; return sourceResolution;
} }
TypeResolution patternResolution = Expressions.typeMustBeString(pattern, functionName(), ParamOrdinal.SECOND); TypeResolution patternResolution = Expressions.typeMustBeString(pattern, sourceText(), ParamOrdinal.SECOND);
if (patternResolution.unresolved()) { if (patternResolution.unresolved()) {
return patternResolution; return patternResolution;
} }
return Expressions.typeMustBeString(replacement, functionName(), ParamOrdinal.THIRD); return Expressions.typeMustBeString(replacement, sourceText(), ParamOrdinal.THIRD);
} }
@Override @Override
@ -124,4 +124,4 @@ public class Replace extends ScalarFunction {
return new Replace(source(), newChildren.get(0), newChildren.get(1), newChildren.get(2)); return new Replace(source(), newChildren.get(0), newChildren.get(1), newChildren.get(2));
} }
} }

View File

@ -45,17 +45,17 @@ public class Substring extends ScalarFunction {
return new TypeResolution("Unresolved children"); return new TypeResolution("Unresolved children");
} }
TypeResolution sourceResolution = Expressions.typeMustBeString(source, functionName(), ParamOrdinal.FIRST); TypeResolution sourceResolution = Expressions.typeMustBeString(source, sourceText(), ParamOrdinal.FIRST);
if (sourceResolution.unresolved()) { if (sourceResolution.unresolved()) {
return sourceResolution; return sourceResolution;
} }
TypeResolution startResolution = Expressions.typeMustBeNumeric(start, functionName(), ParamOrdinal.SECOND); TypeResolution startResolution = Expressions.typeMustBeNumeric(start, sourceText(), ParamOrdinal.SECOND);
if (startResolution.unresolved()) { if (startResolution.unresolved()) {
return startResolution; return startResolution;
} }
return Expressions.typeMustBeNumeric(length, functionName(), ParamOrdinal.THIRD); return Expressions.typeMustBeNumeric(length, sourceText(), ParamOrdinal.THIRD);
} }
@Override @Override
@ -124,4 +124,4 @@ public class Substring extends ScalarFunction {
return new Substring(source(), newChildren.get(0), newChildren.get(1), newChildren.get(2)); return new Substring(source(), newChildren.get(0), newChildren.get(1), newChildren.get(2));
} }
} }

View File

@ -6,8 +6,6 @@
package org.elasticsearch.xpack.sql.expression.predicate; package org.elasticsearch.xpack.sql.expression.predicate;
import org.elasticsearch.xpack.sql.expression.Expression; import org.elasticsearch.xpack.sql.expression.Expression;
import org.elasticsearch.xpack.sql.expression.Expressions;
import org.elasticsearch.xpack.sql.expression.Literal;
import org.elasticsearch.xpack.sql.expression.function.scalar.BinaryScalarFunction; import org.elasticsearch.xpack.sql.expression.function.scalar.BinaryScalarFunction;
import org.elasticsearch.xpack.sql.tree.Source; import org.elasticsearch.xpack.sql.tree.Source;
@ -21,12 +19,10 @@ import java.util.Objects;
*/ */
public abstract class BinaryPredicate<T, U, R, F extends PredicateBiFunction<T, U, R>> extends BinaryScalarFunction { public abstract class BinaryPredicate<T, U, R, F extends PredicateBiFunction<T, U, R>> extends BinaryScalarFunction {
private final String name;
private final F function; private final F function;
protected BinaryPredicate(Source source, Expression left, Expression right, F function) { protected BinaryPredicate(Source source, Expression left, Expression right, F function) {
super(source, left, right); super(source, left, right);
this.name = name(left, right, function.symbol());
this.function = function; this.function = function;
} }
@ -65,11 +61,6 @@ public abstract class BinaryPredicate<T, U, R, F extends PredicateBiFunction<T,
&& Objects.equals(right(), other.right()); && Objects.equals(right(), other.right());
} }
@Override
public String name() {
return name;
}
public String symbol() { public String symbol() {
return function.symbol(); return function.symbol();
} }
@ -77,23 +68,4 @@ public abstract class BinaryPredicate<T, U, R, F extends PredicateBiFunction<T,
public F function() { public F function() {
return function; return function;
} }
private static String name(Expression left, Expression right, String symbol) {
StringBuilder sb = new StringBuilder();
sb.append(Expressions.name(left));
if (!(left instanceof Literal)) {
sb.insert(0, "(");
sb.append(")");
}
sb.append(" ");
sb.append(symbol);
sb.append(" ");
int pos = sb.length();
sb.append(Expressions.name(right));
if (!(right instanceof Literal)) {
sb.insert(pos, "(");
sb.append(")");
}
return sb.toString();
}
} }

View File

@ -18,8 +18,8 @@ import org.elasticsearch.xpack.sql.expression.predicate.logical.BinaryLogicProce
import org.elasticsearch.xpack.sql.expression.predicate.operator.comparison.BinaryComparison; import org.elasticsearch.xpack.sql.expression.predicate.operator.comparison.BinaryComparison;
import org.elasticsearch.xpack.sql.expression.predicate.operator.comparison.BinaryComparisonPipe; import org.elasticsearch.xpack.sql.expression.predicate.operator.comparison.BinaryComparisonPipe;
import org.elasticsearch.xpack.sql.expression.predicate.operator.comparison.BinaryComparisonProcessor.BinaryComparisonOperation; import org.elasticsearch.xpack.sql.expression.predicate.operator.comparison.BinaryComparisonProcessor.BinaryComparisonOperation;
import org.elasticsearch.xpack.sql.tree.Source;
import org.elasticsearch.xpack.sql.tree.NodeInfo; import org.elasticsearch.xpack.sql.tree.NodeInfo;
import org.elasticsearch.xpack.sql.tree.Source;
import org.elasticsearch.xpack.sql.type.DataType; import org.elasticsearch.xpack.sql.type.DataType;
import java.util.List; import java.util.List;
@ -33,7 +33,6 @@ import static org.elasticsearch.xpack.sql.expression.gen.script.ParamsBuilder.pa
// BETWEEN or range - is a mix of gt(e) AND lt(e) // BETWEEN or range - is a mix of gt(e) AND lt(e)
public class Range extends ScalarFunction { public class Range extends ScalarFunction {
private final String name;
private final Expression value, lower, upper; private final Expression value, lower, upper;
private final boolean includeLower, includeUpper; private final boolean includeLower, includeUpper;
@ -45,12 +44,6 @@ public class Range extends ScalarFunction {
this.upper = upper; this.upper = upper;
this.includeLower = includeLower; this.includeLower = includeLower;
this.includeUpper = includeUpper; this.includeUpper = includeUpper;
this.name = name(value, lower, upper, includeLower, includeUpper);
}
@Override
public String name() {
return name;
} }
@Override @Override
@ -212,9 +205,4 @@ public class Range extends ScalarFunction {
return sb.toString(); return sb.toString();
} }
@Override
public String toString() {
return name();
}
} }

View File

@ -27,7 +27,7 @@ public abstract class BinaryLogic extends BinaryOperator<Boolean, Boolean, Boole
@Override @Override
protected TypeResolution resolveInputType(Expression e, Expressions.ParamOrdinal paramOrdinal) { protected TypeResolution resolveInputType(Expression e, Expressions.ParamOrdinal paramOrdinal) {
return Expressions.typeMustBeBoolean(e, functionName(), paramOrdinal); return Expressions.typeMustBeBoolean(e, sourceText(), paramOrdinal);
} }
@Override @Override

View File

@ -12,8 +12,8 @@ import org.elasticsearch.xpack.sql.expression.function.scalar.UnaryScalarFunctio
import org.elasticsearch.xpack.sql.expression.gen.processor.Processor; import org.elasticsearch.xpack.sql.expression.gen.processor.Processor;
import org.elasticsearch.xpack.sql.expression.gen.script.Scripts; import org.elasticsearch.xpack.sql.expression.gen.script.Scripts;
import org.elasticsearch.xpack.sql.expression.predicate.Negatable; import org.elasticsearch.xpack.sql.expression.predicate.Negatable;
import org.elasticsearch.xpack.sql.tree.Source;
import org.elasticsearch.xpack.sql.tree.NodeInfo; import org.elasticsearch.xpack.sql.tree.NodeInfo;
import org.elasticsearch.xpack.sql.tree.Source;
import org.elasticsearch.xpack.sql.type.DataType; import org.elasticsearch.xpack.sql.type.DataType;
public class Not extends UnaryScalarFunction { public class Not extends UnaryScalarFunction {
@ -37,7 +37,7 @@ public class Not extends UnaryScalarFunction {
if (DataType.BOOLEAN == field().dataType()) { if (DataType.BOOLEAN == field().dataType()) {
return TypeResolution.TYPE_RESOLVED; return TypeResolution.TYPE_RESOLVED;
} }
return Expressions.typeMustBeBoolean(field(), functionName(), ParamOrdinal.DEFAULT); return Expressions.typeMustBeBoolean(field(), sourceText(), ParamOrdinal.DEFAULT);
} }
@Override @Override

View File

@ -8,13 +8,12 @@ package org.elasticsearch.xpack.sql.expression.predicate.operator.arithmetic;
import org.elasticsearch.xpack.sql.expression.Expression; import org.elasticsearch.xpack.sql.expression.Expression;
import org.elasticsearch.xpack.sql.expression.Expressions; import org.elasticsearch.xpack.sql.expression.Expressions;
import org.elasticsearch.xpack.sql.expression.Expressions.ParamOrdinal; import org.elasticsearch.xpack.sql.expression.Expressions.ParamOrdinal;
import org.elasticsearch.xpack.sql.expression.NamedExpression;
import org.elasticsearch.xpack.sql.expression.function.scalar.UnaryScalarFunction; import org.elasticsearch.xpack.sql.expression.function.scalar.UnaryScalarFunction;
import org.elasticsearch.xpack.sql.expression.gen.processor.Processor; import org.elasticsearch.xpack.sql.expression.gen.processor.Processor;
import org.elasticsearch.xpack.sql.expression.gen.script.Scripts; import org.elasticsearch.xpack.sql.expression.gen.script.Scripts;
import org.elasticsearch.xpack.sql.expression.predicate.operator.arithmetic.UnaryArithmeticProcessor.UnaryArithmeticOperation; import org.elasticsearch.xpack.sql.expression.predicate.operator.arithmetic.UnaryArithmeticProcessor.UnaryArithmeticOperation;
import org.elasticsearch.xpack.sql.tree.Source;
import org.elasticsearch.xpack.sql.tree.NodeInfo; import org.elasticsearch.xpack.sql.tree.NodeInfo;
import org.elasticsearch.xpack.sql.tree.Source;
import org.elasticsearch.xpack.sql.type.DataType; import org.elasticsearch.xpack.sql.type.DataType;
/** /**
@ -38,7 +37,7 @@ public class Neg extends UnaryScalarFunction {
@Override @Override
protected TypeResolution resolveType() { protected TypeResolution resolveType() {
return Expressions.typeMustBeNumeric(field(), functionName(), ParamOrdinal.DEFAULT); return Expressions.typeMustBeNumeric(field(), sourceText(), ParamOrdinal.DEFAULT);
} }
@Override @Override
@ -51,11 +50,6 @@ public class Neg extends UnaryScalarFunction {
return field().dataType(); return field().dataType();
} }
@Override
public String name() {
return "-" + (field() instanceof NamedExpression && field().resolved() ? Expressions.name(field()) : field().toString());
}
@Override @Override
public String processScript(String script) { public String processScript(String script) {
return Scripts.formatTemplate(Scripts.SQL_SCRIPTS + ".neg(" + script + ")"); return Scripts.formatTemplate(Scripts.SQL_SCRIPTS + ".neg(" + script + ")");

View File

@ -40,18 +40,7 @@ public abstract class BinaryComparison extends BinaryOperator<Object, Object, Bo
return new BinaryComparisonPipe(source(), this, Expressions.pipe(left()), Expressions.pipe(right()), function()); return new BinaryComparisonPipe(source(), this, Expressions.pipe(left()), Expressions.pipe(right()), function());
} }
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append(left());
sb.append(" ");
sb.append(symbol());
sb.append(" ");
sb.append(right());
return sb.toString();
}
public static Integer compare(Object left, Object right) { public static Integer compare(Object left, Object right) {
return Comparisons.compare(left, right); return Comparisons.compare(left, right);
} }
} }

View File

@ -21,7 +21,6 @@ import java.util.ArrayList;
import java.util.LinkedHashSet; import java.util.LinkedHashSet;
import java.util.List; import java.util.List;
import java.util.Objects; import java.util.Objects;
import java.util.StringJoiner;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import static org.elasticsearch.common.logging.LoggerMessageFormat.format; import static org.elasticsearch.common.logging.LoggerMessageFormat.format;
@ -85,13 +84,6 @@ public class In extends ScalarFunction {
return InProcessor.apply(value.fold(), Foldables.valuesOf(list, value.dataType())); return InProcessor.apply(value.fold(), Foldables.valuesOf(list, value.dataType()));
} }
@Override
public String name() {
StringJoiner sj = new StringJoiner(", ", " IN (", ")");
list.forEach(e -> sj.add(Expressions.name(e)));
return Expressions.name(value) + sj.toString();
}
@Override @Override
public ScriptTemplate asScript() { public ScriptTemplate asScript() {
ScriptTemplate leftScript = asScript(value); ScriptTemplate leftScript = asScript(value);

View File

@ -92,6 +92,16 @@ abstract class AbstractBuilder extends SqlBaseBaseVisitor<Object> {
return new Source(new Location(token.getLine(), token.getCharPositionInLine()), text); return new Source(new Location(token.getLine(), token.getCharPositionInLine()), text);
} }
Source source(ParserRuleContext begin, ParserRuleContext end) {
Check.notNull(begin, "begin is null");
Check.notNull(end, "end is null");
Token start = begin.start;
Token stop = end.stop != null ? end.stop : begin.stop;
Interval interval = new Interval(start.getStartIndex(), stop.getStopIndex());
String text = start.getInputStream().getText(interval);
return new Source(new Location(start.getLine(), start.getCharPositionInLine()), text);
}
/** /**
* Retrieves the raw text of the node (without interpreting it as a string literal). * Retrieves the raw text of the node (without interpreting it as a string literal).
*/ */

View File

@ -11,6 +11,7 @@ import org.antlr.v4.runtime.tree.ParseTree;
import org.antlr.v4.runtime.tree.TerminalNode; import org.antlr.v4.runtime.tree.TerminalNode;
import org.elasticsearch.common.Booleans; import org.elasticsearch.common.Booleans;
import org.elasticsearch.common.Strings; import org.elasticsearch.common.Strings;
import org.elasticsearch.common.collect.Tuple;
import org.elasticsearch.xpack.sql.SqlIllegalArgumentException; import org.elasticsearch.xpack.sql.SqlIllegalArgumentException;
import org.elasticsearch.xpack.sql.expression.Alias; import org.elasticsearch.xpack.sql.expression.Alias;
import org.elasticsearch.xpack.sql.expression.Exists; import org.elasticsearch.xpack.sql.expression.Exists;
@ -215,7 +216,7 @@ abstract class ExpressionBuilder extends IdentifierBuilder {
} }
PredicateContext pCtx = ctx.predicate(); PredicateContext pCtx = ctx.predicate();
Source source = source(pCtx); Source source = source(ctx.valueExpression(), ctx);
Expression e = null; Expression e = null;
switch (pCtx.kind.getType()) { switch (pCtx.kind.getType()) {
@ -320,7 +321,7 @@ abstract class ExpressionBuilder extends IdentifierBuilder {
if (value instanceof Literal) { // Minus already processed together with literal number if (value instanceof Literal) { // Minus already processed together with literal number
return value; return value;
} }
return new Neg(source(ctx.operator), value); return new Neg(source(ctx), value);
default: default:
throw new ParsingException(source, "Unknown arithmetic {}", source.text()); throw new ParsingException(source, "Unknown arithmetic {}", source.text());
} }
@ -331,7 +332,7 @@ abstract class ExpressionBuilder extends IdentifierBuilder {
Expression left = expression(ctx.left); Expression left = expression(ctx.left);
Expression right = expression(ctx.right); Expression right = expression(ctx.right);
Source source = source(ctx.operator); Source source = source(ctx);
switch (ctx.operator.getType()) { switch (ctx.operator.getType()) {
case SqlBaseParser.ASTERISK: case SqlBaseParser.ASTERISK:
@ -611,7 +612,7 @@ abstract class ExpressionBuilder extends IdentifierBuilder {
Interval<?> timeInterval = value instanceof Period ? new IntervalYearMonth((Period) value, Interval<?> timeInterval = value instanceof Period ? new IntervalYearMonth((Period) value,
intervalType) : new IntervalDayTime((Duration) value, intervalType); intervalType) : new IntervalDayTime((Duration) value, intervalType);
return new Literal(source(interval), text(interval), timeInterval, timeInterval.dataType()); return new Literal(source(interval), timeInterval, timeInterval.dataType());
} }
private TemporalAmount of(NumberContext valueNumeric, TimeUnit unit) { private TemporalAmount of(NumberContext valueNumeric, TimeUnit unit) {
@ -689,23 +690,24 @@ abstract class ExpressionBuilder extends IdentifierBuilder {
@Override @Override
public Literal visitDecimalLiteral(DecimalLiteralContext ctx) { public Literal visitDecimalLiteral(DecimalLiteralContext ctx) {
String string = (hasMinusFromParent(ctx) ? "-" : "") + ctx.getText(); Tuple<Source, String> tuple = withMinus(ctx);
try { try {
return new Literal(source(ctx), Double.valueOf(StringUtils.parseDouble(string)), DataType.DOUBLE); return new Literal(tuple.v1(), Double.valueOf(StringUtils.parseDouble(tuple.v2())), DataType.DOUBLE);
} catch (SqlIllegalArgumentException siae) { } catch (SqlIllegalArgumentException siae) {
throw new ParsingException(source(ctx), siae.getMessage()); throw new ParsingException(tuple.v1(), siae.getMessage());
} }
} }
@Override @Override
public Literal visitIntegerLiteral(IntegerLiteralContext ctx) { public Literal visitIntegerLiteral(IntegerLiteralContext ctx) {
String string = (hasMinusFromParent(ctx) ? "-" : "") + ctx.getText(); Tuple<Source, String> tuple = withMinus(ctx);
long value; long value;
try { try {
value = Long.valueOf(StringUtils.parseLong(string)); value = Long.valueOf(StringUtils.parseLong(tuple.v2()));
} catch (SqlIllegalArgumentException siae) { } catch (SqlIllegalArgumentException siae) {
throw new ParsingException(source(ctx), siae.getMessage()); throw new ParsingException(tuple.v1(), siae.getMessage());
} }
Object val = Long.valueOf(value); Object val = Long.valueOf(value);
@ -715,7 +717,7 @@ abstract class ExpressionBuilder extends IdentifierBuilder {
type = DataType.INTEGER; type = DataType.INTEGER;
val = Integer.valueOf((int) value); val = Integer.valueOf((int) value);
} }
return new Literal(source(ctx), val, type); return new Literal(tuple.v1(), val, type);
} }
@Override @Override
@ -876,7 +878,30 @@ abstract class ExpressionBuilder extends IdentifierBuilder {
return new Literal(source(ctx), string, DataType.KEYWORD); return new Literal(source(ctx), string, DataType.KEYWORD);
} }
private boolean hasMinusFromParent(SqlBaseParser.NumberContext ctx) { /**
* Return the source and the value of the given number,
* taking into account MINUS (-) if needed.
*/
private static Tuple<Source, String> withMinus(NumberContext ctx) {
String string = ctx.getText();
Source source = minusAwareSource(ctx);
if (source != null) {
string = "-" + string;
} else {
source = source(ctx);
}
return new Tuple<>(source, string);
}
/**
* Checks the presence of MINUS (-) in the parent and if found,
* returns the parent source or null otherwise.
* Parsing of the value should not depend on the returned source
* as it might contain extra spaces.
*/
private static Source minusAwareSource(SqlBaseParser.NumberContext ctx) {
ParserRuleContext parentCtx = ctx.getParent(); ParserRuleContext parentCtx = ctx.getParent();
if (parentCtx != null) { if (parentCtx != null) {
if (parentCtx instanceof SqlBaseParser.NumericLiteralContext) { if (parentCtx instanceof SqlBaseParser.NumericLiteralContext) {
@ -886,17 +911,23 @@ abstract class ExpressionBuilder extends IdentifierBuilder {
if (parentCtx != null && parentCtx instanceof SqlBaseParser.ValueExpressionDefaultContext) { if (parentCtx != null && parentCtx instanceof SqlBaseParser.ValueExpressionDefaultContext) {
parentCtx = parentCtx.getParent(); parentCtx = parentCtx.getParent();
if (parentCtx != null && parentCtx instanceof SqlBaseParser.ArithmeticUnaryContext) { if (parentCtx != null && parentCtx instanceof SqlBaseParser.ArithmeticUnaryContext) {
return ((ArithmeticUnaryContext) parentCtx).MINUS() != null; if (((ArithmeticUnaryContext) parentCtx).MINUS() != null) {
return source(parentCtx);
}
} }
} }
} }
} else if (parentCtx instanceof SqlBaseParser.IntervalContext) { } else if (parentCtx instanceof SqlBaseParser.IntervalContext) {
IntervalContext ic = (IntervalContext) parentCtx; IntervalContext ic = (IntervalContext) parentCtx;
return ic.sign != null && ic.sign.getType() == SqlBaseParser.MINUS; if (ic.sign != null && ic.sign.getType() == SqlBaseParser.MINUS) {
return source(ic);
}
} else if (parentCtx instanceof SqlBaseParser.SysTypesContext) { } else if (parentCtx instanceof SqlBaseParser.SysTypesContext) {
return ((SysTypesContext) parentCtx).MINUS() != null; if (((SysTypesContext) parentCtx).MINUS() != null) {
return source(parentCtx);
}
} }
} }
return false; return null;
} }
} }

View File

@ -239,7 +239,7 @@ public class VerifierErrorMessagesTests extends ESTestCase {
} }
public void testGroupByOrderByScalarOverNonGrouped() { public void testGroupByOrderByScalarOverNonGrouped() {
assertEquals("1:50: Cannot order by non-grouped column [YEAR(date [Z])], expected [text]", assertEquals("1:50: Cannot order by non-grouped column [YEAR(date)], expected [text]",
error("SELECT MAX(int) FROM test GROUP BY text ORDER BY YEAR(date)")); error("SELECT MAX(int) FROM test GROUP BY text ORDER BY YEAR(date)"));
} }
@ -249,7 +249,7 @@ public class VerifierErrorMessagesTests extends ESTestCase {
} }
public void testGroupByOrderByScalarOverNonGrouped_WithHaving() { public void testGroupByOrderByScalarOverNonGrouped_WithHaving() {
assertEquals("1:71: Cannot order by non-grouped column [YEAR(date [Z])], expected [text]", assertEquals("1:71: Cannot order by non-grouped column [YEAR(date)], expected [text]",
error("SELECT MAX(int) FROM test GROUP BY text HAVING MAX(int) > 10 ORDER BY YEAR(date)")); error("SELECT MAX(int) FROM test GROUP BY text HAVING MAX(int) > 10 ORDER BY YEAR(date)"));
} }
@ -373,12 +373,12 @@ public class VerifierErrorMessagesTests extends ESTestCase {
} }
public void testNotSupportedAggregateOnDate() { public void testNotSupportedAggregateOnDate() {
assertEquals("1:8: [AVG] argument must be [numeric], found value [date] type [date]", assertEquals("1:8: [AVG(date)] argument must be [numeric], found value [date] type [date]",
error("SELECT AVG(date) FROM test")); error("SELECT AVG(date) FROM test"));
} }
public void testNotSupportedAggregateOnString() { public void testNotSupportedAggregateOnString() {
assertEquals("1:8: [MAX] argument must be [numeric or date], found value [keyword] type [keyword]", assertEquals("1:8: [MAX(keyword)] argument must be [numeric or date], found value [keyword] type [keyword]",
error("SELECT MAX(keyword) FROM test")); error("SELECT MAX(keyword) FROM test"));
} }
@ -388,53 +388,53 @@ public class VerifierErrorMessagesTests extends ESTestCase {
} }
public void testInvalidTypeForNumericFunction_WithOneArg() { public void testInvalidTypeForNumericFunction_WithOneArg() {
assertEquals("1:8: [COS] argument must be [numeric], found value [foo] type [keyword]", assertEquals("1:8: [COS] argument must be [numeric], found value ['foo'] type [keyword]",
error("SELECT COS('foo')")); error("SELECT COS('foo')"));
} }
public void testInvalidTypeForBooleanFunction_WithOneArg() { public void testInvalidTypeForBooleanFunction_WithOneArg() {
assertEquals("1:8: [NOT] argument must be [boolean], found value [foo] type [keyword]", assertEquals("1:8: [NOT 'foo'] argument must be [boolean], found value ['foo'] type [keyword]",
error("SELECT NOT 'foo'")); error("SELECT NOT 'foo'"));
} }
public void testInvalidTypeForStringFunction_WithTwoArgs() { public void testInvalidTypeForStringFunction_WithTwoArgs() {
assertEquals("1:8: [CONCAT] first argument must be [string], found value [1] type [integer]", assertEquals("1:8: [CONCAT(1, 'bar')] first argument must be [string], found value [1] type [integer]",
error("SELECT CONCAT(1, 'bar')")); error("SELECT CONCAT(1, 'bar')"));
assertEquals("1:8: [CONCAT] second argument must be [string], found value [2] type [integer]", assertEquals("1:8: [CONCAT('foo', 2)] second argument must be [string], found value [2] type [integer]",
error("SELECT CONCAT('foo', 2)")); error("SELECT CONCAT('foo', 2)"));
} }
public void testInvalidTypeForNumericFunction_WithTwoArgs() { public void testInvalidTypeForNumericFunction_WithTwoArgs() {
assertEquals("1:8: [TRUNCATE] first argument must be [numeric], found value [foo] type [keyword]", assertEquals("1:8: [TRUNCATE('foo', 2)] first argument must be [numeric], found value ['foo'] type [keyword]",
error("SELECT TRUNCATE('foo', 2)")); error("SELECT TRUNCATE('foo', 2)"));
assertEquals("1:8: [TRUNCATE] second argument must be [numeric], found value [bar] type [keyword]", assertEquals("1:8: [TRUNCATE(1.2, 'bar')] second argument must be [numeric], found value ['bar'] type [keyword]",
error("SELECT TRUNCATE(1.2, 'bar')")); error("SELECT TRUNCATE(1.2, 'bar')"));
} }
public void testInvalidTypeForBooleanFuntion_WithTwoArgs() { public void testInvalidTypeForBooleanFuntion_WithTwoArgs() {
assertEquals("1:8: [OR] first argument must be [boolean], found value [1] type [integer]", assertEquals("1:8: [1 OR true] first argument must be [boolean], found value [1] type [integer]",
error("SELECT 1 OR true")); error("SELECT 1 OR true"));
assertEquals("1:8: [OR] second argument must be [boolean], found value [2] type [integer]", assertEquals("1:8: [true OR 2] second argument must be [boolean], found value [2] type [integer]",
error("SELECT true OR 2")); error("SELECT true OR 2"));
} }
public void testInvalidTypeForFunction_WithThreeArgs() { public void testInvalidTypeForFunction_WithThreeArgs() {
assertEquals("1:8: [REPLACE] first argument must be [string], found value [1] type [integer]", assertEquals("1:8: [REPLACE(1, 'foo', 'bar')] first argument must be [string], found value [1] type [integer]",
error("SELECT REPLACE(1, 'foo', 'bar')")); error("SELECT REPLACE(1, 'foo', 'bar')"));
assertEquals("1:8: [REPLACE] second argument must be [string], found value [2] type [integer]", assertEquals("1:8: [REPLACE('text', 2, 'bar')] second argument must be [string], found value [2] type [integer]",
error("SELECT REPLACE('text', 2, 'bar')")); error("SELECT REPLACE('text', 2, 'bar')"));
assertEquals("1:8: [REPLACE] third argument must be [string], found value [3] type [integer]", assertEquals("1:8: [REPLACE('text', 'foo', 3)] third argument must be [string], found value [3] type [integer]",
error("SELECT REPLACE('text', 'foo', 3)")); error("SELECT REPLACE('text', 'foo', 3)"));
} }
public void testInvalidTypeForFunction_WithFourArgs() { public void testInvalidTypeForFunction_WithFourArgs() {
assertEquals("1:8: [INSERT] first argument must be [string], found value [1] type [integer]", assertEquals("1:8: [INSERT(1, 1, 2, 'new')] first argument must be [string], found value [1] type [integer]",
error("SELECT INSERT(1, 1, 2, 'new')")); error("SELECT INSERT(1, 1, 2, 'new')"));
assertEquals("1:8: [INSERT] second argument must be [numeric], found value [foo] type [keyword]", assertEquals("1:8: [INSERT('text', 'foo', 2, 'new')] second argument must be [numeric], found value ['foo'] type [keyword]",
error("SELECT INSERT('text', 'foo', 2, 'new')")); error("SELECT INSERT('text', 'foo', 2, 'new')"));
assertEquals("1:8: [INSERT] third argument must be [numeric], found value [bar] type [keyword]", assertEquals("1:8: [INSERT('text', 1, 'bar', 'new')] third argument must be [numeric], found value ['bar'] type [keyword]",
error("SELECT INSERT('text', 1, 'bar', 'new')")); error("SELECT INSERT('text', 1, 'bar', 'new')"));
assertEquals("1:8: [INSERT] fourth argument must be [string], found value [3] type [integer]", assertEquals("1:8: [INSERT('text', 1, 2, 3)] fourth argument must be [string], found value [3] type [integer]",
error("SELECT INSERT('text', 1, 2, 3)")); error("SELECT INSERT('text', 1, 2, 3)"));
} }
@ -508,7 +508,7 @@ public class VerifierErrorMessagesTests extends ESTestCase {
} }
public void testHistogramInFilter() { public void testHistogramInFilter() {
assertEquals("1:63: Cannot filter on grouping function [HISTOGRAM(date)], use its argument instead", assertEquals("1:63: Cannot filter on grouping function [HISTOGRAM(date, INTERVAL 1 MONTH)], use its argument instead",
error("SELECT HISTOGRAM(date, INTERVAL 1 MONTH) AS h FROM test WHERE " error("SELECT HISTOGRAM(date, INTERVAL 1 MONTH) AS h FROM test WHERE "
+ "HISTOGRAM(date, INTERVAL 1 MONTH) > CAST('2000-01-01' AS DATE) GROUP BY h")); + "HISTOGRAM(date, INTERVAL 1 MONTH) > CAST('2000-01-01' AS DATE) GROUP BY h"));
} }
@ -522,8 +522,8 @@ public class VerifierErrorMessagesTests extends ESTestCase {
public void testGroupByScalarOnTopOfGrouping() { public void testGroupByScalarOnTopOfGrouping() {
assertEquals( assertEquals(
"1:14: Cannot combine [HISTOGRAM(date)] grouping function inside GROUP BY, " "1:14: Cannot combine [HISTOGRAM(date, INTERVAL 1 MONTH)] grouping function inside "
+ "found [MONTH_OF_YEAR(HISTOGRAM(date) [Z])]; consider moving the expression inside the histogram", + "GROUP BY, found [MONTH(HISTOGRAM(date, INTERVAL 1 MONTH))]; consider moving the expression inside the histogram",
error("SELECT MONTH(HISTOGRAM(date, INTERVAL 1 MONTH)) AS h FROM test GROUP BY h")); error("SELECT MONTH(HISTOGRAM(date, INTERVAL 1 MONTH)) AS h FROM test GROUP BY h"));
} }

View File

@ -14,6 +14,8 @@ import org.elasticsearch.xpack.sql.expression.predicate.operator.arithmetic.Mod;
import org.elasticsearch.xpack.sql.expression.predicate.operator.arithmetic.Mul; import org.elasticsearch.xpack.sql.expression.predicate.operator.arithmetic.Mul;
import org.elasticsearch.xpack.sql.expression.predicate.operator.arithmetic.Neg; import org.elasticsearch.xpack.sql.expression.predicate.operator.arithmetic.Neg;
import org.elasticsearch.xpack.sql.expression.predicate.operator.arithmetic.Sub; import org.elasticsearch.xpack.sql.expression.predicate.operator.arithmetic.Sub;
import org.elasticsearch.xpack.sql.tree.Location;
import org.elasticsearch.xpack.sql.tree.Source;
import org.elasticsearch.xpack.sql.type.DataType; import org.elasticsearch.xpack.sql.type.DataType;
import org.elasticsearch.xpack.sql.type.EsField; import org.elasticsearch.xpack.sql.type.EsField;
@ -23,29 +25,40 @@ import static org.elasticsearch.xpack.sql.tree.Source.EMPTY;
public class NamedExpressionTests extends ESTestCase { public class NamedExpressionTests extends ESTestCase {
public void testArithmeticFunctionName() { public void testArithmeticFunctionName() {
Add add = new Add(EMPTY, l(5), l(2)); String e = "5 + 2";
assertEquals("5 + 2", add.name()); Add add = new Add(s(e), l(5), l(2));
assertEquals(e, add.sourceText());
Div div = new Div(EMPTY, l(5), l(2)); e = "5 / 2";
assertEquals("5 / 2", div.name()); Div div = new Div(s(e), l(5), l(2));
assertEquals(e, div.sourceText());
Mod mod = new Mod(EMPTY, l(5), l(2)); e = "5%2";
assertEquals("5 % 2", mod.name()); Mod mod = new Mod(s(e), l(5), l(2));
assertEquals(e, mod.sourceText());
Mul mul = new Mul(EMPTY, l(5), l(2)); e = "5 * 2";
assertEquals("5 * 2", mul.name()); Mul mul = new Mul(s(e), l(5), l(2));
assertEquals(e, mul.sourceText());
Sub sub = new Sub(EMPTY, l(5), l(2)); e = "5 -2";
assertEquals("5 - 2", sub.name()); Sub sub = new Sub(s(e), l(5), l(2));
assertEquals(e, sub.sourceText());
Neg neg = new Neg(EMPTY, l(5)); e = " - 5";
assertEquals("-5", neg.name()); Neg neg = new Neg(s(e), l(5));
assertEquals(e, neg.sourceText());
} }
public void testNameForArithmeticFunctionAppliedOnTableColumn() { public void testNameForArithmeticFunctionAppliedOnTableColumn() {
FieldAttribute fa = new FieldAttribute(EMPTY, "myField", new EsField("myESField", DataType.INTEGER, emptyMap(), true)); FieldAttribute fa = new FieldAttribute(EMPTY, "myField", new EsField("myESField", DataType.INTEGER, emptyMap(), true));
Add add = new Add(EMPTY, fa, l(10)); String e = "myField + 10";
assertEquals("(myField) + 10", add.name()); Add add = new Add(s(e), fa, l(10));
assertEquals(e, add.sourceText());
}
private static Source s(String text) {
return new Source(Location.EMPTY, text);
} }
private static Literal l(Object value) { private static Literal l(Object value) {

View File

@ -7,6 +7,7 @@ package org.elasticsearch.xpack.sql.expression.function.scalar.datetime;
import org.elasticsearch.test.ESTestCase; import org.elasticsearch.test.ESTestCase;
import org.elasticsearch.xpack.sql.expression.Literal; import org.elasticsearch.xpack.sql.expression.Literal;
import org.elasticsearch.xpack.sql.tree.Source;
import org.elasticsearch.xpack.sql.type.DataType; import org.elasticsearch.xpack.sql.type.DataType;
import java.time.ZoneId; import java.time.ZoneId;
@ -27,6 +28,6 @@ public class DayOfYearTests extends ESTestCase {
} }
private DayOfYear build(Object value, ZoneId zoneId) { private DayOfYear build(Object value, ZoneId zoneId) {
return new DayOfYear(null, new Literal(null, value, DataType.DATE), zoneId); return new DayOfYear(Source.EMPTY, new Literal(Source.EMPTY, value, DataType.DATE), zoneId);
} }
} }

View File

@ -585,7 +585,7 @@ public class OptimizerTests extends ESTestCase {
BooleanLiteralsOnTheRight swapLiteralsToRight = new BooleanLiteralsOnTheRight(); BooleanLiteralsOnTheRight swapLiteralsToRight = new BooleanLiteralsOnTheRight();
BinaryComparisonSimplification bcSimpl = new BinaryComparisonSimplification(); BinaryComparisonSimplification bcSimpl = new BinaryComparisonSimplification();
FieldAttribute fa = getFieldAttribute(); FieldAttribute fa = getFieldAttribute();
Source source = new Source(1, 10, StringUtils.EMPTY); Source source = new Source(1, 10, "IS_NULL(a)");
Expression e = bcSimpl.rule(swapLiteralsToRight.rule(new NullEquals(source, fa, NULL))); Expression e = bcSimpl.rule(swapLiteralsToRight.rule(new NullEquals(source, fa, NULL)));
assertEquals(IsNull.class, e.getClass()); assertEquals(IsNull.class, e.getClass());

View File

@ -80,12 +80,12 @@ public class EscapedFunctionsTests extends ESTestCase {
public void testFunctionNoArg() { public void testFunctionNoArg() {
Function f = function("SCORE()"); Function f = function("SCORE()");
assertEquals("SCORE", f.functionName()); assertEquals("{fn SCORE()}", f.sourceText());
} }
public void testFunctionOneArg() { public void testFunctionOneArg() {
Function f = function("ABS(foo)"); Function f = function("ABS(foo)");
assertEquals("ABS", f.functionName()); assertEquals("{fn ABS(foo)}", f.sourceText());
assertEquals(1, f.arguments().size()); assertEquals(1, f.arguments().size());
Expression arg = f.arguments().get(0); Expression arg = f.arguments().get(0);
assertThat(arg, instanceOf(UnresolvedAttribute.class)); assertThat(arg, instanceOf(UnresolvedAttribute.class));
@ -95,75 +95,77 @@ public class EscapedFunctionsTests extends ESTestCase {
public void testFunctionOneArgFunction() { public void testFunctionOneArgFunction() {
Function f = function("ABS({fn SCORE()})"); Function f = function("ABS({fn SCORE()})");
assertEquals("ABS", f.functionName()); assertEquals("{fn ABS({fn SCORE()})}", f.sourceText());
assertEquals(1, f.arguments().size()); assertEquals(1, f.arguments().size());
Expression arg = f.arguments().get(0); Expression arg = f.arguments().get(0);
assertThat(arg, instanceOf(UnresolvedFunction.class)); assertThat(arg, instanceOf(UnresolvedFunction.class));
UnresolvedFunction uf = (UnresolvedFunction) arg; UnresolvedFunction uf = (UnresolvedFunction) arg;
assertThat(uf.name(), is("SCORE")); assertThat(uf.sourceText(), is("{fn SCORE()}"));
} }
public void testFunctionFloorWithExtract() { public void testFunctionFloorWithExtract() {
Function f = function("CAST({fn FLOOR({fn EXTRACT(YEAR FROM \"foo\")})} AS int)"); String e = "CAST({fn FLOOR({fn EXTRACT(YEAR FROM \"foo\")})} AS int)";
assertEquals("CAST", f.functionName()); Function f = function(e);
assertEquals(e, f.sourceText());
assertEquals(1, f.arguments().size()); assertEquals(1, f.arguments().size());
Expression arg = f.arguments().get(0); Expression arg = f.arguments().get(0);
assertThat(arg, instanceOf(UnresolvedFunction.class)); assertThat(arg, instanceOf(UnresolvedFunction.class));
f = (Function) arg; f = (Function) arg;
assertEquals("FLOOR", f.functionName()); assertEquals("{fn FLOOR({fn EXTRACT(YEAR FROM \"foo\")})}", f.sourceText());
assertEquals(1, f.arguments().size()); assertEquals(1, f.arguments().size());
arg = f.arguments().get(0); arg = f.arguments().get(0);
assertThat(arg, instanceOf(UnresolvedFunction.class)); assertThat(arg, instanceOf(UnresolvedFunction.class));
UnresolvedFunction uf = (UnresolvedFunction) arg; UnresolvedFunction uf = (UnresolvedFunction) arg;
assertThat(uf.name(), is("YEAR")); assertThat(uf.sourceText(), is("EXTRACT(YEAR FROM \"foo\")"));
} }
public void testFunctionWithFunctionWithArg() { public void testFunctionWithFunctionWithArg() {
Function f = function("POWER(foo, {fn POWER({fn SCORE()}, {fN SCORE()})})"); Function f = function("POWER(foo, {fn POWER({fn SCORE()}, {fN SCORE()})})");
assertEquals("POWER", f.functionName()); assertEquals("{fn POWER(foo, {fn POWER({fn SCORE()}, {fN SCORE()})})}", f.sourceText());
assertEquals(2, f.arguments().size()); assertEquals(2, f.arguments().size());
Expression arg = f.arguments().get(1); Expression arg = f.arguments().get(1);
assertThat(arg, instanceOf(UnresolvedFunction.class)); assertThat(arg, instanceOf(UnresolvedFunction.class));
UnresolvedFunction uf = (UnresolvedFunction) arg; UnresolvedFunction uf = (UnresolvedFunction) arg;
assertThat(uf.name(), is("POWER")); assertThat(uf.sourceText(), is("{fn POWER({fn SCORE()}, {fN SCORE()})}"));
assertEquals(2, uf.arguments().size()); assertEquals(2, uf.arguments().size());
List<Expression> args = uf.arguments(); List<Expression> args = uf.arguments();
arg = args.get(0); arg = args.get(0);
assertThat(arg, instanceOf(UnresolvedFunction.class)); assertThat(arg, instanceOf(UnresolvedFunction.class));
uf = (UnresolvedFunction) arg; uf = (UnresolvedFunction) arg;
assertThat(uf.name(), is("SCORE")); assertThat(uf.sourceText(), is("{fn SCORE()}"));
arg = args.get(1); arg = args.get(1);
assertThat(arg, instanceOf(UnresolvedFunction.class)); assertThat(arg, instanceOf(UnresolvedFunction.class));
uf = (UnresolvedFunction) arg; uf = (UnresolvedFunction) arg;
assertThat(uf.name(), is("SCORE")); assertThat(uf.sourceText(), is("{fN SCORE()}"));
} }
public void testFunctionWithFunctionWithArgAndParams() { public void testFunctionWithFunctionWithArgAndParams() {
Function f = (Function) parser.createExpression("POWER(?, {fn POWER({fn ABS(?)}, {fN ABS(?)})})", String e = "POWER(?, {fn POWER({fn ABS(?)}, {fN ABS(?)})})";
Function f = (Function) parser.createExpression(e,
asList(new SqlTypedParamValue(DataType.LONG.esType, 1), asList(new SqlTypedParamValue(DataType.LONG.esType, 1),
new SqlTypedParamValue(DataType.LONG.esType, 1), new SqlTypedParamValue(DataType.LONG.esType, 1),
new SqlTypedParamValue(DataType.LONG.esType, 1))); new SqlTypedParamValue(DataType.LONG.esType, 1)));
assertEquals("POWER", f.functionName()); assertEquals(e, f.sourceText());
assertEquals(2, f.arguments().size()); assertEquals(2, f.arguments().size());
Expression arg = f.arguments().get(1); Expression arg = f.arguments().get(1);
assertThat(arg, instanceOf(UnresolvedFunction.class)); assertThat(arg, instanceOf(UnresolvedFunction.class));
UnresolvedFunction uf = (UnresolvedFunction) arg; UnresolvedFunction uf = (UnresolvedFunction) arg;
assertThat(uf.name(), is("POWER")); assertEquals("{fn POWER({fn ABS(?)}, {fN ABS(?)})}", uf.sourceText());
assertEquals(2, uf.arguments().size()); assertEquals(2, uf.arguments().size());
List<Expression> args = uf.arguments(); List<Expression> args = uf.arguments();
arg = args.get(0); arg = args.get(0);
assertThat(arg, instanceOf(UnresolvedFunction.class)); assertThat(arg, instanceOf(UnresolvedFunction.class));
uf = (UnresolvedFunction) arg; uf = (UnresolvedFunction) arg;
assertThat(uf.name(), is("ABS")); assertThat(uf.sourceText(), is("{fn ABS(?)}"));
arg = args.get(1); arg = args.get(1);
assertThat(arg, instanceOf(UnresolvedFunction.class)); assertThat(arg, instanceOf(UnresolvedFunction.class));
uf = (UnresolvedFunction) arg; uf = (UnresolvedFunction) arg;
assertThat(uf.name(), is("ABS")); assertThat(uf.sourceText(), is("{fN ABS(?)}"));
} }
public void testDateLiteral() { public void testDateLiteral() {

View File

@ -26,7 +26,6 @@ import java.time.temporal.TemporalAmount;
import java.util.Locale; import java.util.Locale;
import static java.lang.String.format; import static java.lang.String.format;
import static org.hamcrest.core.StringStartsWith.startsWith;
public class ExpressionTests extends ESTestCase { public class ExpressionTests extends ESTestCase {
@ -36,7 +35,7 @@ public class ExpressionTests extends ESTestCase {
Expression lt = parser.createExpression("LEFT()"); Expression lt = parser.createExpression("LEFT()");
assertEquals(UnresolvedFunction.class, lt.getClass()); assertEquals(UnresolvedFunction.class, lt.getClass());
UnresolvedFunction uf = (UnresolvedFunction) lt; UnresolvedFunction uf = (UnresolvedFunction) lt;
assertEquals("LEFT", uf.functionName()); assertEquals("LEFT()", uf.sourceText());
} }
public void testLiteralBoolean() { public void testLiteralBoolean() {
@ -182,10 +181,10 @@ public class ExpressionTests extends ESTestCase {
} }
public void testLiteralTimesLiteral() { public void testLiteralTimesLiteral() {
Expression expr = parser.createExpression("10*2"); Expression expr = parser.createExpression("10 *2");
assertEquals(Mul.class, expr.getClass()); assertEquals(Mul.class, expr.getClass());
Mul mul = (Mul) expr; Mul mul = (Mul) expr;
assertEquals("10 * 2", mul.name()); assertEquals("10 *2", mul.sourceText());
assertEquals(DataType.INTEGER, mul.dataType()); assertEquals(DataType.INTEGER, mul.dataType());
} }
@ -193,39 +192,46 @@ public class ExpressionTests extends ESTestCase {
Expression expr = parser.createExpression("PI()*2"); Expression expr = parser.createExpression("PI()*2");
assertEquals(Mul.class, expr.getClass()); assertEquals(Mul.class, expr.getClass());
Mul mul = (Mul) expr; Mul mul = (Mul) expr;
assertEquals("(PI) * 2", mul.name()); assertEquals("PI()*2", mul.sourceText());
}
public void testNegativeLiteral() {
Expression expr = parser.createExpression("- 6");
assertEquals(Literal.class, expr.getClass());
assertEquals("- 6", expr.sourceText());
} }
public void testComplexArithmetic() { public void testComplexArithmetic() {
Expression expr = parser.createExpression("-(((a-2)-(-3))+b)"); String sql = "-(((a-2)-(-3))+b)";
Expression expr = parser.createExpression(sql);
assertEquals(Neg.class, expr.getClass()); assertEquals(Neg.class, expr.getClass());
Neg neg = (Neg) expr; Neg neg = (Neg) expr;
assertThat(neg.name(), startsWith("-(((a) - 2) - -3) + (b)#")); assertEquals(sql, neg.sourceText());
assertEquals(1, neg.children().size()); assertEquals(1, neg.children().size());
assertEquals(Add.class, neg.children().get(0).getClass()); assertEquals(Add.class, neg.children().get(0).getClass());
Add add = (Add) neg.children().get(0); Add add = (Add) neg.children().get(0);
assertEquals("(((a) - 2) - -3) + (b)", add.name()); assertEquals("((a-2)-(-3))+b", add.sourceText());
assertEquals(2, add.children().size()); assertEquals(2, add.children().size());
assertEquals("?b", add.children().get(1).toString()); assertEquals("?b", add.children().get(1).toString());
assertEquals(Sub.class, add.children().get(0).getClass()); assertEquals(Sub.class, add.children().get(0).getClass());
Sub sub1 = (Sub) add.children().get(0); Sub sub1 = (Sub) add.children().get(0);
assertEquals("((a) - 2) - -3", sub1.name()); assertEquals("(a-2)-(-3)", sub1.sourceText());
assertEquals(2, sub1.children().size()); assertEquals(2, sub1.children().size());
assertEquals(Literal.class, sub1.children().get(1).getClass()); assertEquals(Literal.class, sub1.children().get(1).getClass());
assertEquals("-3", ((Literal) sub1.children().get(1)).name()); assertEquals("-3", ((Literal) sub1.children().get(1)).sourceText());
assertEquals(Sub.class, sub1.children().get(0).getClass()); assertEquals(Sub.class, sub1.children().get(0).getClass());
Sub sub2 = (Sub) sub1.children().get(0); Sub sub2 = (Sub) sub1.children().get(0);
assertEquals(2, sub2.children().size()); assertEquals(2, sub2.children().size());
assertEquals("?a", sub2.children().get(0).toString()); assertEquals("?a", sub2.children().get(0).toString());
assertEquals(Literal.class, sub2.children().get(1).getClass()); assertEquals(Literal.class, sub2.children().get(1).getClass());
assertEquals("2", ((Literal) sub2.children().get(1)).name()); assertEquals("2", ((Literal) sub2.children().get(1)).sourceText());
} }
public void testEquals() { public void testEquals() {
Expression expr = parser.createExpression("a = 10"); Expression expr = parser.createExpression("a = 10");
assertEquals(Equals.class, expr.getClass()); assertEquals(Equals.class, expr.getClass());
Equals eq = (Equals) expr; Equals eq = (Equals) expr;
assertEquals("(a) == 10", eq.name()); assertEquals("a = 10", eq.sourceText());
assertEquals(2, eq.children().size()); assertEquals(2, eq.children().size());
} }
@ -233,7 +239,7 @@ public class ExpressionTests extends ESTestCase {
Expression expr = parser.createExpression("a <=> 10"); Expression expr = parser.createExpression("a <=> 10");
assertEquals(NullEquals.class, expr.getClass()); assertEquals(NullEquals.class, expr.getClass());
NullEquals nullEquals = (NullEquals) expr; NullEquals nullEquals = (NullEquals) expr;
assertEquals("(a) <=> 10", nullEquals.name()); assertEquals("a <=> 10", nullEquals.sourceText());
assertEquals(2, nullEquals.children().size()); assertEquals(2, nullEquals.children().size());
} }
@ -241,12 +247,12 @@ public class ExpressionTests extends ESTestCase {
Expression expr = parser.createExpression("a != 10"); Expression expr = parser.createExpression("a != 10");
assertEquals(NotEquals.class, expr.getClass()); assertEquals(NotEquals.class, expr.getClass());
NotEquals neq = (NotEquals) expr; NotEquals neq = (NotEquals) expr;
assertEquals("(a) != 10", neq.name()); assertEquals("a != 10", neq.sourceText());
assertEquals(2, neq.children().size()); assertEquals(2, neq.children().size());
} }
public void testCastWithUnquotedDataType() { public void testCastWithUnquotedDataType() {
Expression expr = parser.createExpression("CAST(10*2 AS long)"); Expression expr = parser.createExpression("CAST(10* 2 AS long)");
assertEquals(Cast.class, expr.getClass()); assertEquals(Cast.class, expr.getClass());
Cast cast = (Cast) expr; Cast cast = (Cast) expr;
assertEquals(DataType.INTEGER, cast.from()); assertEquals(DataType.INTEGER, cast.from());
@ -254,7 +260,7 @@ public class ExpressionTests extends ESTestCase {
assertEquals(DataType.LONG, cast.dataType()); assertEquals(DataType.LONG, cast.dataType());
assertEquals(Mul.class, cast.field().getClass()); assertEquals(Mul.class, cast.field().getClass());
Mul mul = (Mul) cast.field(); Mul mul = (Mul) cast.field();
assertEquals("10 * 2", mul.name()); assertEquals("10* 2", mul.sourceText());
assertEquals(DataType.INTEGER, mul.dataType()); assertEquals(DataType.INTEGER, mul.dataType());
} }
@ -267,7 +273,7 @@ public class ExpressionTests extends ESTestCase {
assertEquals(DataType.LONG, cast.dataType()); assertEquals(DataType.LONG, cast.dataType());
assertEquals(Mul.class, cast.field().getClass()); assertEquals(Mul.class, cast.field().getClass());
Mul mul = (Mul) cast.field(); Mul mul = (Mul) cast.field();
assertEquals("10 * 2", mul.name()); assertEquals("10*2", mul.sourceText());
assertEquals(DataType.INTEGER, mul.dataType()); assertEquals(DataType.INTEGER, mul.dataType());
} }
@ -285,20 +291,22 @@ public class ExpressionTests extends ESTestCase {
assertEquals(DataType.LONG, cast.dataType()); assertEquals(DataType.LONG, cast.dataType());
assertEquals(Mul.class, cast.field().getClass()); assertEquals(Mul.class, cast.field().getClass());
Mul mul = (Mul) cast.field(); Mul mul = (Mul) cast.field();
assertEquals("10 * 2", mul.name()); assertEquals("10*2", mul.sourceText());
assertEquals(DataType.INTEGER, mul.dataType()); assertEquals(DataType.INTEGER, mul.dataType());
} }
public void testConvertWithQuotedDataType() { public void testConvertWithQuotedDataType() {
Expression expr = parser.createExpression("CONVERT(10*2, \"LonG\")"); String e = "CONVERT(10*2, \"LonG\")";
Expression expr = parser.createExpression(e);
assertEquals(Cast.class, expr.getClass()); assertEquals(Cast.class, expr.getClass());
Cast cast = (Cast) expr; Cast cast = (Cast) expr;
assertEquals(e, cast.sourceText());
assertEquals(DataType.INTEGER, cast.from()); assertEquals(DataType.INTEGER, cast.from());
assertEquals(DataType.LONG, cast.to()); assertEquals(DataType.LONG, cast.to());
assertEquals(DataType.LONG, cast.dataType()); assertEquals(DataType.LONG, cast.dataType());
assertEquals(Mul.class, cast.field().getClass()); assertEquals(Mul.class, cast.field().getClass());
Mul mul = (Mul) cast.field(); Mul mul = (Mul) cast.field();
assertEquals("10 * 2", mul.name()); assertEquals("10*2", mul.sourceText());
assertEquals(DataType.INTEGER, mul.dataType()); assertEquals(DataType.INTEGER, mul.dataType());
} }
@ -334,7 +342,7 @@ public class ExpressionTests extends ESTestCase {
Expression expr = parser.createExpression("CURRENT_TIMESTAMP"); Expression expr = parser.createExpression("CURRENT_TIMESTAMP");
assertEquals(UnresolvedFunction.class, expr.getClass()); assertEquals(UnresolvedFunction.class, expr.getClass());
UnresolvedFunction ur = (UnresolvedFunction) expr; UnresolvedFunction ur = (UnresolvedFunction) expr;
assertEquals("CURRENT_TIMESTAMP", ur.name()); assertEquals("CURRENT_TIMESTAMP", ur.sourceText());
assertEquals(0, ur.children().size()); assertEquals(0, ur.children().size());
} }
@ -342,7 +350,7 @@ public class ExpressionTests extends ESTestCase {
Expression expr = parser.createExpression("CURRENT_TIMESTAMP(4)"); Expression expr = parser.createExpression("CURRENT_TIMESTAMP(4)");
assertEquals(UnresolvedFunction.class, expr.getClass()); assertEquals(UnresolvedFunction.class, expr.getClass());
UnresolvedFunction ur = (UnresolvedFunction) expr; UnresolvedFunction ur = (UnresolvedFunction) expr;
assertEquals("CURRENT_TIMESTAMP", ur.name()); assertEquals("CURRENT_TIMESTAMP(4)", ur.sourceText());
assertEquals(1, ur.children().size()); assertEquals(1, ur.children().size());
Expression child = ur.children().get(0); Expression child = ur.children().get(0);
assertEquals(Literal.class, child.getClass()); assertEquals(Literal.class, child.getClass());

View File

@ -6,6 +6,7 @@
package org.elasticsearch.xpack.sql.parser; package org.elasticsearch.xpack.sql.parser;
import com.google.common.base.Joiner; import com.google.common.base.Joiner;
import org.elasticsearch.test.ESTestCase; import org.elasticsearch.test.ESTestCase;
import org.elasticsearch.xpack.sql.expression.NamedExpression; import org.elasticsearch.xpack.sql.expression.NamedExpression;
import org.elasticsearch.xpack.sql.expression.Order; import org.elasticsearch.xpack.sql.expression.Order;
@ -15,6 +16,7 @@ import org.elasticsearch.xpack.sql.expression.function.UnresolvedFunction;
import org.elasticsearch.xpack.sql.expression.predicate.fulltext.MatchQueryPredicate; import org.elasticsearch.xpack.sql.expression.predicate.fulltext.MatchQueryPredicate;
import org.elasticsearch.xpack.sql.expression.predicate.fulltext.MultiMatchQueryPredicate; import org.elasticsearch.xpack.sql.expression.predicate.fulltext.MultiMatchQueryPredicate;
import org.elasticsearch.xpack.sql.expression.predicate.fulltext.StringQueryPredicate; import org.elasticsearch.xpack.sql.expression.predicate.fulltext.StringQueryPredicate;
import org.elasticsearch.xpack.sql.expression.predicate.operator.arithmetic.Add;
import org.elasticsearch.xpack.sql.expression.predicate.operator.comparison.In; import org.elasticsearch.xpack.sql.expression.predicate.operator.comparison.In;
import org.elasticsearch.xpack.sql.parser.SqlBaseParser.BooleanExpressionContext; import org.elasticsearch.xpack.sql.parser.SqlBaseParser.BooleanExpressionContext;
import org.elasticsearch.xpack.sql.parser.SqlBaseParser.QueryPrimaryDefaultContext; import org.elasticsearch.xpack.sql.parser.SqlBaseParser.QueryPrimaryDefaultContext;
@ -60,12 +62,17 @@ public class SqlParserTests extends ESTestCase {
public void testSelectScore() { public void testSelectScore() {
UnresolvedFunction f = singleProjection(project(parseStatement("SELECT SCORE() FROM foo")), UnresolvedFunction.class); UnresolvedFunction f = singleProjection(project(parseStatement("SELECT SCORE() FROM foo")), UnresolvedFunction.class);
assertEquals("SCORE", f.functionName()); assertEquals("SCORE()", f.sourceText());
}
public void testSelectAddWithParanthesis() {
Add f = singleProjection(project(parseStatement("SELECT (1 + 2)")), Add.class);
assertEquals("1 + 2", f.sourceText());
} }
public void testSelectRightFunction() { public void testSelectRightFunction() {
UnresolvedFunction f = singleProjection(project(parseStatement("SELECT RIGHT()")), UnresolvedFunction.class); UnresolvedFunction f = singleProjection(project(parseStatement("SELECT RIGHT()")), UnresolvedFunction.class);
assertEquals("RIGHT", f.functionName()); assertEquals("RIGHT()", f.sourceText());
} }
public void testsSelectNonReservedKeywords() { public void testsSelectNonReservedKeywords() {
@ -102,13 +109,13 @@ public class SqlParserTests extends ESTestCase {
public void testOrderByScore() { public void testOrderByScore() {
Order.OrderDirection dir = randomFrom(Order.OrderDirection.values()); Order.OrderDirection dir = randomFrom(Order.OrderDirection.values());
OrderBy ob = orderBy(parseStatement("SELECT * FROM foo ORDER BY SCORE()" + stringForDirection(dir))); OrderBy ob = orderBy(parseStatement("SELECT * FROM foo ORDER BY SCORE( )" + stringForDirection(dir)));
assertThat(ob.order(), hasSize(1)); assertThat(ob.order(), hasSize(1));
Order o = ob.order().get(0); Order o = ob.order().get(0);
assertEquals(dir, o.direction()); assertEquals(dir, o.direction());
assertThat(o.child(), instanceOf(UnresolvedFunction.class)); assertThat(o.child(), instanceOf(UnresolvedFunction.class));
UnresolvedFunction f = (UnresolvedFunction) o.child(); UnresolvedFunction f = (UnresolvedFunction) o.child();
assertEquals("SCORE", f.functionName()); assertEquals("SCORE( )", f.sourceText());
} }
public void testOrderByTwo() { public void testOrderByTwo() {
@ -299,7 +306,7 @@ public class SqlParserTests extends ESTestCase {
In in = (In) filter.condition(); In in = (In) filter.condition();
assertEquals("?a", in.value().toString()); assertEquals("?a", in.value().toString());
assertEquals(noChildren, in.list().size()); assertEquals(noChildren, in.list().size());
assertThat(in.list().get(0).toString(), startsWith("(a) + (b)#")); assertThat(in.list().get(0).toString(), startsWith("a + b#"));
} }
public void testDecrementOfDepthCounter() { public void testDecrementOfDepthCounter() {

View File

@ -76,7 +76,7 @@ public class QueryFolderTests extends ESTestCase {
assertEquals(EmptyExecutable.class, le.executable().getClass()); assertEquals(EmptyExecutable.class, le.executable().getClass());
EmptyExecutable ee = (EmptyExecutable) le.executable(); EmptyExecutable ee = (EmptyExecutable) le.executable();
assertEquals(1, ee.output().size()); assertEquals(1, ee.output().size());
assertThat(ee.output().get(0).toString(), startsWith("E{c}#")); assertThat(ee.output().get(0).toString(), startsWith("E(){c}#"));
} }
public void testLocalExecWithPrunedFilterWithFunctionAndAggregation() { public void testLocalExecWithPrunedFilterWithFunctionAndAggregation() {
@ -86,7 +86,7 @@ public class QueryFolderTests extends ESTestCase {
assertEquals(EmptyExecutable.class, le.executable().getClass()); assertEquals(EmptyExecutable.class, le.executable().getClass());
EmptyExecutable ee = (EmptyExecutable) le.executable(); EmptyExecutable ee = (EmptyExecutable) le.executable();
assertEquals(1, ee.output().size()); assertEquals(1, ee.output().size());
assertThat(ee.output().get(0).toString(), startsWith("E{c}#")); assertThat(ee.output().get(0).toString(), startsWith("E(){c}#"));
} }
public void testLocalExecWithoutFromClause() { public void testLocalExecWithoutFromClause() {
@ -96,9 +96,9 @@ public class QueryFolderTests extends ESTestCase {
assertEquals(SingletonExecutable.class, le.executable().getClass()); assertEquals(SingletonExecutable.class, le.executable().getClass());
SingletonExecutable ee = (SingletonExecutable) le.executable(); SingletonExecutable ee = (SingletonExecutable) le.executable();
assertEquals(3, ee.output().size()); assertEquals(3, ee.output().size());
assertThat(ee.output().get(0).toString(), startsWith("E{c}#")); assertThat(ee.output().get(0).toString(), startsWith("E(){c}#"));
assertThat(ee.output().get(1).toString(), startsWith("foo{c}#")); assertThat(ee.output().get(1).toString(), startsWith("'foo'{c}#"));
assertThat(ee.output().get(2).toString(), startsWith("ABS(10){c}#")); assertThat(ee.output().get(2).toString(), startsWith("abs(10){c}#"));
} }
public void testLocalExecWithoutFromClauseWithPrunedFilter() { public void testLocalExecWithoutFromClauseWithPrunedFilter() {
@ -108,7 +108,7 @@ public class QueryFolderTests extends ESTestCase {
assertEquals(EmptyExecutable.class, le.executable().getClass()); assertEquals(EmptyExecutable.class, le.executable().getClass());
EmptyExecutable ee = (EmptyExecutable) le.executable(); EmptyExecutable ee = (EmptyExecutable) le.executable();
assertEquals(1, ee.output().size()); assertEquals(1, ee.output().size());
assertThat(ee.output().get(0).toString(), startsWith("E{c}#")); assertThat(ee.output().get(0).toString(), startsWith("E(){c}#"));
} }
public void testFoldingOfIsNull() { public void testFoldingOfIsNull() {
@ -137,7 +137,7 @@ public class QueryFolderTests extends ESTestCase {
EmptyExecutable ee = (EmptyExecutable) le.executable(); EmptyExecutable ee = (EmptyExecutable) le.executable();
assertEquals(2, ee.output().size()); assertEquals(2, ee.output().size());
assertThat(ee.output().get(0).toString(), startsWith("keyword{f}#")); assertThat(ee.output().get(0).toString(), startsWith("keyword{f}#"));
assertThat(ee.output().get(1).toString(), startsWith("MAX(int){a->")); assertThat(ee.output().get(1).toString(), startsWith("max(int){a->"));
} }
public void testFoldingBooleanOrNull_WhereClause() { public void testFoldingBooleanOrNull_WhereClause() {
@ -159,7 +159,7 @@ public class QueryFolderTests extends ESTestCase {
"\"lang\":\"painless\",\"params\":{\"v0\":10}},")); "\"lang\":\"painless\",\"params\":{\"v0\":10}},"));
assertEquals(2, ee.output().size()); assertEquals(2, ee.output().size());
assertThat(ee.output().get(0).toString(), startsWith("keyword{f}#")); assertThat(ee.output().get(0).toString(), startsWith("keyword{f}#"));
assertThat(ee.output().get(1).toString(), startsWith("MAX(int){a->")); assertThat(ee.output().get(1).toString(), startsWith("max(int){a->"));
} }
public void testFoldingOfIsNotNull() { public void testFoldingOfIsNotNull() {
@ -208,7 +208,7 @@ public class QueryFolderTests extends ESTestCase {
EmptyExecutable ee = (EmptyExecutable) le.executable(); EmptyExecutable ee = (EmptyExecutable) le.executable();
assertEquals(2, ee.output().size()); assertEquals(2, ee.output().size());
assertThat(ee.output().get(0).toString(), startsWith("keyword{f}#")); assertThat(ee.output().get(0).toString(), startsWith("keyword{f}#"));
assertThat(ee.output().get(1).toString(), startsWith("MAX(int){a->")); assertThat(ee.output().get(1).toString(), startsWith("max(int){a->"));
} }
public void testFoldingToLocalExecWithProjectWithGroupBy_WithHaving_WithOrderAndLimit() { public void testFoldingToLocalExecWithProjectWithGroupBy_WithHaving_WithOrderAndLimit() {
@ -219,7 +219,7 @@ public class QueryFolderTests extends ESTestCase {
EmptyExecutable ee = (EmptyExecutable) le.executable(); EmptyExecutable ee = (EmptyExecutable) le.executable();
assertEquals(2, ee.output().size()); assertEquals(2, ee.output().size());
assertThat(ee.output().get(0).toString(), startsWith("keyword{f}#")); assertThat(ee.output().get(0).toString(), startsWith("keyword{f}#"));
assertThat(ee.output().get(1).toString(), startsWith("MAX(int){a->")); assertThat(ee.output().get(1).toString(), startsWith("max(int){a->"));
} }
public void testGroupKeyTypes_Boolean() { public void testGroupKeyTypes_Boolean() {
@ -232,7 +232,7 @@ public class QueryFolderTests extends ESTestCase {
"\"lang\":\"painless\",\"params\":{\"v0\":\"int\",\"v1\":10}},\"missing_bucket\":true," + "\"lang\":\"painless\",\"params\":{\"v0\":\"int\",\"v1\":10}},\"missing_bucket\":true," +
"\"value_type\":\"boolean\",\"order\":\"asc\"}}}]}}}")); "\"value_type\":\"boolean\",\"order\":\"asc\"}}}]}}}"));
assertEquals(2, ee.output().size()); assertEquals(2, ee.output().size());
assertThat(ee.output().get(0).toString(), startsWith("COUNT(1){a->")); assertThat(ee.output().get(0).toString(), startsWith("count(*){a->"));
assertThat(ee.output().get(1).toString(), startsWith("a{s->")); assertThat(ee.output().get(1).toString(), startsWith("a{s->"));
} }
@ -246,7 +246,7 @@ public class QueryFolderTests extends ESTestCase {
"\"lang\":\"painless\",\"params\":{\"v0\":\"int\",\"v1\":10}},\"missing_bucket\":true," + "\"lang\":\"painless\",\"params\":{\"v0\":\"int\",\"v1\":10}},\"missing_bucket\":true," +
"\"value_type\":\"long\",\"order\":\"asc\"}}}]}}}")); "\"value_type\":\"long\",\"order\":\"asc\"}}}]}}}"));
assertEquals(2, ee.output().size()); assertEquals(2, ee.output().size());
assertThat(ee.output().get(0).toString(), startsWith("COUNT(1){a->")); assertThat(ee.output().get(0).toString(), startsWith("count(*){a->"));
assertThat(ee.output().get(1).toString(), startsWith("a{s->")); assertThat(ee.output().get(1).toString(), startsWith("a{s->"));
} }
@ -260,7 +260,7 @@ public class QueryFolderTests extends ESTestCase {
"\"lang\":\"painless\",\"params\":{\"v0\":\"int\"}},\"missing_bucket\":true," + "\"lang\":\"painless\",\"params\":{\"v0\":\"int\"}},\"missing_bucket\":true," +
"\"value_type\":\"double\",\"order\":\"asc\"}}}]}}}")); "\"value_type\":\"double\",\"order\":\"asc\"}}}]}}}"));
assertEquals(2, ee.output().size()); assertEquals(2, ee.output().size());
assertThat(ee.output().get(0).toString(), startsWith("COUNT(1){a->")); assertThat(ee.output().get(0).toString(), startsWith("count(*){a->"));
assertThat(ee.output().get(1).toString(), startsWith("a{s->")); assertThat(ee.output().get(1).toString(), startsWith("a{s->"));
} }
@ -274,7 +274,7 @@ public class QueryFolderTests extends ESTestCase {
"\"lang\":\"painless\",\"params\":{\"v0\":\"keyword\"}},\"missing_bucket\":true," + "\"lang\":\"painless\",\"params\":{\"v0\":\"keyword\"}},\"missing_bucket\":true," +
"\"value_type\":\"string\",\"order\":\"asc\"}}}]}}}")); "\"value_type\":\"string\",\"order\":\"asc\"}}}]}}}"));
assertEquals(2, ee.output().size()); assertEquals(2, ee.output().size());
assertThat(ee.output().get(0).toString(), startsWith("COUNT(1){a->")); assertThat(ee.output().get(0).toString(), startsWith("count(*){a->"));
assertThat(ee.output().get(1).toString(), startsWith("a{s->")); assertThat(ee.output().get(1).toString(), startsWith("a{s->"));
} }
@ -288,7 +288,7 @@ public class QueryFolderTests extends ESTestCase {
"\"lang\":\"painless\",\"params\":{\"v0\":\"keyword\",\"v1\":\"IP\"}}," + "\"lang\":\"painless\",\"params\":{\"v0\":\"keyword\",\"v1\":\"IP\"}}," +
"\"missing_bucket\":true,\"value_type\":\"ip\",\"order\":\"asc\"}}}]}}}")); "\"missing_bucket\":true,\"value_type\":\"ip\",\"order\":\"asc\"}}}]}}}"));
assertEquals(2, ee.output().size()); assertEquals(2, ee.output().size());
assertThat(ee.output().get(0).toString(), startsWith("COUNT(1){a->")); assertThat(ee.output().get(0).toString(), startsWith("count(*){a->"));
assertThat(ee.output().get(1).toString(), startsWith("a{s->")); assertThat(ee.output().get(1).toString(), startsWith("a{s->"));
} }
@ -303,7 +303,7 @@ public class QueryFolderTests extends ESTestCase {
"\"v0\":\"date\",\"v1\":\"P1Y2M\",\"v2\":\"INTERVAL_YEAR_TO_MONTH\"}},\"missing_bucket\":true," + "\"v0\":\"date\",\"v1\":\"P1Y2M\",\"v2\":\"INTERVAL_YEAR_TO_MONTH\"}},\"missing_bucket\":true," +
"\"value_type\":\"date\",\"order\":\"asc\"}}}]}}}")); "\"value_type\":\"date\",\"order\":\"asc\"}}}]}}}"));
assertEquals(2, ee.output().size()); assertEquals(2, ee.output().size());
assertThat(ee.output().get(0).toString(), startsWith("COUNT(1){a->")); assertThat(ee.output().get(0).toString(), startsWith("count(*){a->"));
assertThat(ee.output().get(1).toString(), startsWith("a{s->")); assertThat(ee.output().get(1).toString(), startsWith("a{s->"));
} }

View File

@ -277,7 +277,7 @@ public class QueryTranslatorTests extends ESTestCase {
AggFilter aggFilter = translation.aggFilter; AggFilter aggFilter = translation.aggFilter;
assertEquals("InternalSqlScriptUtils.nullSafeFilter(InternalSqlScriptUtils.isNull(params.a0))", assertEquals("InternalSqlScriptUtils.nullSafeFilter(InternalSqlScriptUtils.isNull(params.a0))",
aggFilter.scriptTemplate().toString()); aggFilter.scriptTemplate().toString());
assertThat(aggFilter.scriptTemplate().params().toString(), startsWith("[{a=MAX(int){a->")); assertThat(aggFilter.scriptTemplate().params().toString(), startsWith("[{a=max(int){a->"));
} }
public void testTranslateIsNotNullExpression_HavingClause_Painless() { public void testTranslateIsNotNullExpression_HavingClause_Painless() {
@ -290,7 +290,7 @@ public class QueryTranslatorTests extends ESTestCase {
AggFilter aggFilter = translation.aggFilter; AggFilter aggFilter = translation.aggFilter;
assertEquals("InternalSqlScriptUtils.nullSafeFilter(InternalSqlScriptUtils.isNotNull(params.a0))", assertEquals("InternalSqlScriptUtils.nullSafeFilter(InternalSqlScriptUtils.isNotNull(params.a0))",
aggFilter.scriptTemplate().toString()); aggFilter.scriptTemplate().toString());
assertThat(aggFilter.scriptTemplate().params().toString(), startsWith("[{a=MAX(int){a->")); assertThat(aggFilter.scriptTemplate().params().toString(), startsWith("[{a=max(int){a->"));
} }
public void testTranslateInExpression_WhereClause() { public void testTranslateInExpression_WhereClause() {
@ -328,8 +328,10 @@ public class QueryTranslatorTests extends ESTestCase {
Expression condition = ((Filter) p.children().get(0)).condition(); Expression condition = ((Filter) p.children().get(0)).condition();
assertFalse(condition.foldable()); assertFalse(condition.foldable());
SqlIllegalArgumentException ex = expectThrows(SqlIllegalArgumentException.class, () -> QueryTranslator.toQuery(condition, false)); SqlIllegalArgumentException ex = expectThrows(SqlIllegalArgumentException.class, () -> QueryTranslator.toQuery(condition, false));
assertEquals("Line 1:52: Comparisons against variables are not (currently) supported; " + assertEquals(
"offender [keyword] in [keyword IN (foo, bar, keyword)]", ex.getMessage()); "Line 1:52: Comparisons against variables are not (currently) supported; "
+ "offender [keyword] in [keyword IN ('foo', 'bar', keyword)]",
ex.getMessage());
} }
public void testTranslateInExpression_WhereClause_Painless() { public void testTranslateInExpression_WhereClause_Painless() {
@ -358,7 +360,7 @@ public class QueryTranslatorTests extends ESTestCase {
AggFilter aggFilter = translation.aggFilter; AggFilter aggFilter = translation.aggFilter;
assertEquals("InternalSqlScriptUtils.nullSafeFilter(InternalSqlScriptUtils.in(params.a0, params.v0))", assertEquals("InternalSqlScriptUtils.nullSafeFilter(InternalSqlScriptUtils.in(params.a0, params.v0))",
aggFilter.scriptTemplate().toString()); aggFilter.scriptTemplate().toString());
assertThat(aggFilter.scriptTemplate().params().toString(), startsWith("[{a=MAX(int){a->")); assertThat(aggFilter.scriptTemplate().params().toString(), startsWith("[{a=max(int){a->"));
assertThat(aggFilter.scriptTemplate().params().toString(), endsWith(", {v=[10, 20]}]")); assertThat(aggFilter.scriptTemplate().params().toString(), endsWith(", {v=[10, 20]}]"));
} }
@ -372,7 +374,7 @@ public class QueryTranslatorTests extends ESTestCase {
AggFilter aggFilter = translation.aggFilter; AggFilter aggFilter = translation.aggFilter;
assertEquals("InternalSqlScriptUtils.nullSafeFilter(InternalSqlScriptUtils.in(params.a0, params.v0))", assertEquals("InternalSqlScriptUtils.nullSafeFilter(InternalSqlScriptUtils.in(params.a0, params.v0))",
aggFilter.scriptTemplate().toString()); aggFilter.scriptTemplate().toString());
assertThat(aggFilter.scriptTemplate().params().toString(), startsWith("[{a=MAX(int){a->")); assertThat(aggFilter.scriptTemplate().params().toString(), startsWith("[{a=max(int){a->"));
assertThat(aggFilter.scriptTemplate().params().toString(), endsWith(", {v=[10]}]")); assertThat(aggFilter.scriptTemplate().params().toString(), endsWith(", {v=[10]}]"));
} }
@ -387,7 +389,7 @@ public class QueryTranslatorTests extends ESTestCase {
AggFilter aggFilter = translation.aggFilter; AggFilter aggFilter = translation.aggFilter;
assertEquals("InternalSqlScriptUtils.nullSafeFilter(InternalSqlScriptUtils.in(params.a0, params.v0))", assertEquals("InternalSqlScriptUtils.nullSafeFilter(InternalSqlScriptUtils.in(params.a0, params.v0))",
aggFilter.scriptTemplate().toString()); aggFilter.scriptTemplate().toString());
assertThat(aggFilter.scriptTemplate().params().toString(), startsWith("[{a=MAX(int){a->")); assertThat(aggFilter.scriptTemplate().params().toString(), startsWith("[{a=max(int){a->"));
assertThat(aggFilter.scriptTemplate().params().toString(), endsWith(", {v=[10, null, 20, 30]}]")); assertThat(aggFilter.scriptTemplate().params().toString(), endsWith(", {v=[10, null, 20, 30]}]"));
} }
@ -406,7 +408,7 @@ public class QueryTranslatorTests extends ESTestCase {
assertEquals("InternalSqlScriptUtils.nullSafeFilter(InternalSqlScriptUtils.gt(InternalSqlScriptUtils." + assertEquals("InternalSqlScriptUtils.nullSafeFilter(InternalSqlScriptUtils.gt(InternalSqlScriptUtils." +
operation.name().toLowerCase(Locale.ROOT) + "(params.a0),params.v0))", operation.name().toLowerCase(Locale.ROOT) + "(params.a0),params.v0))",
aggFilter.scriptTemplate().toString()); aggFilter.scriptTemplate().toString());
assertThat(aggFilter.scriptTemplate().params().toString(), startsWith("[{a=MAX(int){a->")); assertThat(aggFilter.scriptTemplate().params().toString(), startsWith("[{a=max(int){a->"));
assertThat(aggFilter.scriptTemplate().params().toString(), endsWith(", {v=10}]")); assertThat(aggFilter.scriptTemplate().params().toString(), endsWith(", {v=10}]"));
} }

View File

@ -9,12 +9,13 @@ import org.elasticsearch.test.ESTestCase;
import org.elasticsearch.xpack.sql.SqlIllegalArgumentException; import org.elasticsearch.xpack.sql.SqlIllegalArgumentException;
import org.elasticsearch.xpack.sql.TestUtils; import org.elasticsearch.xpack.sql.TestUtils;
import org.elasticsearch.xpack.sql.expression.Literal; import org.elasticsearch.xpack.sql.expression.Literal;
import org.elasticsearch.xpack.sql.tree.Location;
import org.elasticsearch.xpack.sql.tree.Source;
import org.elasticsearch.xpack.sql.type.DataTypeConversion.Conversion; import org.elasticsearch.xpack.sql.type.DataTypeConversion.Conversion;
import java.time.ZonedDateTime; import java.time.ZonedDateTime;
import static org.elasticsearch.xpack.sql.expression.function.scalar.datetime.DateTimeTestUtils.dateTime; import static org.elasticsearch.xpack.sql.expression.function.scalar.datetime.DateTimeTestUtils.dateTime;
import static org.elasticsearch.xpack.sql.tree.Source.EMPTY;
import static org.elasticsearch.xpack.sql.type.DataType.BOOLEAN; import static org.elasticsearch.xpack.sql.type.DataType.BOOLEAN;
import static org.elasticsearch.xpack.sql.type.DataType.BYTE; import static org.elasticsearch.xpack.sql.type.DataType.BYTE;
import static org.elasticsearch.xpack.sql.type.DataType.DATE; import static org.elasticsearch.xpack.sql.type.DataType.DATE;
@ -291,9 +292,10 @@ public class DataTypeConversionTests extends ESTestCase {
} }
public void testIpToString() { public void testIpToString() {
Source s = new Source(Location.EMPTY, "10.0.0.1");
Conversion ipToString = conversionFor(IP, KEYWORD); Conversion ipToString = conversionFor(IP, KEYWORD);
assertEquals("10.0.0.1", ipToString.convert(new Literal(EMPTY, "10.0.0.1", IP))); assertEquals("10.0.0.1", ipToString.convert(new Literal(s, "10.0.0.1", IP)));
Conversion stringToIp = conversionFor(KEYWORD, IP); Conversion stringToIp = conversionFor(KEYWORD, IP);
assertEquals("10.0.0.1", ipToString.convert(stringToIp.convert(Literal.of(EMPTY, "10.0.0.1")))); assertEquals("10.0.0.1", ipToString.convert(stringToIp.convert(Literal.of(s, "10.0.0.1"))));
} }
} }