From 5efcbbbd26b9296eacf259fedf9eef4f23dc26d6 Mon Sep 17 00:00:00 2001 From: Georgy Shabunin Date: Wed, 27 Nov 2013 18:14:47 +0100 Subject: [PATCH 01/37] Correct grammar and interface for parser --- src/com/etk/parser/SELECT.g4 | 33 +- src/com/etk/parser/SELECT.tokens | 6 +- src/com/etk/parser/SELECTBaseListener.java | 49 +- src/com/etk/parser/SELECTLexer.java | 95 ++-- src/com/etk/parser/SELECTLexer.tokens | 6 +- src/com/etk/parser/SELECTListener.java | 51 +- src/com/etk/parser/SELECTMain.java | 33 +- src/com/etk/parser/SELECTParser.java | 513 +++++++++++--------- src/com/etk/parser/SelectObject.java | 43 ++ src/com/etk/parser/SelectQueryToObject.java | 55 +++ 10 files changed, 515 insertions(+), 369 deletions(-) create mode 100644 src/com/etk/parser/SelectObject.java create mode 100644 src/com/etk/parser/SelectQueryToObject.java diff --git a/src/com/etk/parser/SELECT.g4 b/src/com/etk/parser/SELECT.g4 index c4071ff..a80475e 100644 --- a/src/com/etk/parser/SELECT.g4 +++ b/src/com/etk/parser/SELECT.g4 @@ -13,10 +13,10 @@ selectList: | derivedColumn (',' derivedColumn)* ; derivedColumn: - COLUMNNAME (asClause)? ; + columnName (asClause)? ; asClause: - 'AS' COLUMNNAME ; + 'AS' columnName ; tableExpression : fromClause @@ -26,21 +26,16 @@ tableExpression : ; fromClause : - 'FROM' tableReferenceList ; - -tableReferenceList : - tableReference (','tableReference)* ; - -tableReference : - tablePrimary ; - + 'FROM' tablePrimary (',' tablePrimary)* ; tablePrimary : - TABLENAME (('AS')? TABLENAME - ( '(' derivedColumnList ')' )? )?; + tableName ('AS' tablePrimaryAs)? ; + +tablePrimaryAs : + tableName ( '(' derivedColumnList ')' )? ; derivedColumnList : - COLUMNNAME (( ',' COLUMNNAME)+)? ; + columnName (',' columnName)* ; whereClause : 'WHERE' searchCondition; @@ -82,9 +77,11 @@ parenthizedBooleanValueExpression : -COLUMNNAME: ID ; -TABLENAME: ID ; -ID : ID_LETTER(ID_LETTER | DIGIT)*; -ID_LETTER : [a_zA_Z] | '_' ; -fragment DIGIT : [0-9] ; +columnName: ID; +tableName: ID; +ID : ID_LETTER (ID_LETTER | DIGIT)* ; +fragment ID_LETTER : 'a'..'z'|'A'..'Z'|'_' ; +fragment DIGIT : '0'..'9' ; +WS : [ \t\r\n]+ -> skip ; // Define whitespace rule, toss it out + diff --git a/src/com/etk/parser/SELECT.tokens b/src/com/etk/parser/SELECT.tokens index db84f1c..ec5aabc 100644 --- a/src/com/etk/parser/SELECT.tokens +++ b/src/com/etk/parser/SELECT.tokens @@ -1,6 +1,6 @@ +WS=19 T__16=1 T__15=2 -ID_LETTER=21 T__12=5 T__11=6 T__14=3 @@ -10,10 +10,8 @@ T__0=17 T__3=14 T__10=7 T__2=15 -ID=20 -COLUMNNAME=18 +ID=18 T__9=8 -TABLENAME=19 T__8=9 T__7=10 T__6=11 diff --git a/src/com/etk/parser/SELECTBaseListener.java b/src/com/etk/parser/SELECTBaseListener.java index 43658a2..c9c53c3 100644 --- a/src/com/etk/parser/SELECTBaseListener.java +++ b/src/com/etk/parser/SELECTBaseListener.java @@ -1,4 +1,4 @@ -// Generated from C:\Users\Georgy\IdeaProjects\SELECTParser\src\SELECT.g4 by ANTLR 4.1 +package com.etk.parser;// Generated from C:\Users\Georgy\IdeaProjects\SELECTParser\src\SELECT.g4 by ANTLR 4.1 import org.antlr.v4.runtime.ParserRuleContext; import org.antlr.v4.runtime.misc.NotNull; @@ -24,19 +24,6 @@ public class SELECTBaseListener implements SELECTListener { */ @Override public void exitWhereClause(@NotNull SELECTParser.WhereClauseContext ctx) { } - /** - * {@inheritDoc} - *

- * The default implementation does nothing. - */ - @Override public void enterTableReference(@NotNull SELECTParser.TableReferenceContext ctx) { } - /** - * {@inheritDoc} - *

- * The default implementation does nothing. - */ - @Override public void exitTableReference(@NotNull SELECTParser.TableReferenceContext ctx) { } - /** * {@inheritDoc} *

@@ -172,26 +159,26 @@ public class SELECTBaseListener implements SELECTListener { *

* The default implementation does nothing. */ - @Override public void enterTableReferenceList(@NotNull SELECTParser.TableReferenceListContext ctx) { } + @Override public void enterBooleanPrimary(@NotNull SELECTParser.BooleanPrimaryContext ctx) { } /** * {@inheritDoc} *

* The default implementation does nothing. */ - @Override public void exitTableReferenceList(@NotNull SELECTParser.TableReferenceListContext ctx) { } + @Override public void exitBooleanPrimary(@NotNull SELECTParser.BooleanPrimaryContext ctx) { } /** * {@inheritDoc} *

* The default implementation does nothing. */ - @Override public void enterBooleanPrimary(@NotNull SELECTParser.BooleanPrimaryContext ctx) { } + @Override public void enterTablePrimaryAs(@NotNull SELECTParser.TablePrimaryAsContext ctx) { } /** * {@inheritDoc} *

* The default implementation does nothing. */ - @Override public void exitBooleanPrimary(@NotNull SELECTParser.BooleanPrimaryContext ctx) { } + @Override public void exitTablePrimaryAs(@NotNull SELECTParser.TablePrimaryAsContext ctx) { } /** * {@inheritDoc} @@ -219,6 +206,19 @@ public class SELECTBaseListener implements SELECTListener { */ @Override public void exitSetQuantifier(@NotNull SELECTParser.SetQuantifierContext ctx) { } + /** + * {@inheritDoc} + *

+ * The default implementation does nothing. + */ + @Override public void enterTableName(@NotNull SELECTParser.TableNameContext ctx) { } + /** + * {@inheritDoc} + *

+ * The default implementation does nothing. + */ + @Override public void exitTableName(@NotNull SELECTParser.TableNameContext ctx) { } + /** * {@inheritDoc} *

@@ -245,6 +245,19 @@ public class SELECTBaseListener implements SELECTListener { */ @Override public void exitSearchCondition(@NotNull SELECTParser.SearchConditionContext ctx) { } + /** + * {@inheritDoc} + *

+ * The default implementation does nothing. + */ + @Override public void enterColumnName(@NotNull SELECTParser.ColumnNameContext ctx) { } + /** + * {@inheritDoc} + *

+ * The default implementation does nothing. + */ + @Override public void exitColumnName(@NotNull SELECTParser.ColumnNameContext ctx) { } + /** * {@inheritDoc} *

diff --git a/src/com/etk/parser/SELECTLexer.java b/src/com/etk/parser/SELECTLexer.java index 2a64849..85bd936 100644 --- a/src/com/etk/parser/SELECTLexer.java +++ b/src/com/etk/parser/SELECTLexer.java @@ -1,12 +1,13 @@ -// Generated from C:\Users\Georgy\IdeaProjects\SELECTParser\src\SELECT.g4 by ANTLR 4.1 -import org.antlr.v4.runtime.Lexer; +package com.etk.parser;// Generated from C:\Users\Georgy\IdeaProjects\SELECTParser\src\SELECT.g4 by ANTLR 4.1 + import org.antlr.v4.runtime.CharStream; -import org.antlr.v4.runtime.Token; -import org.antlr.v4.runtime.TokenStream; -import org.antlr.v4.runtime.*; -import org.antlr.v4.runtime.atn.*; +import org.antlr.v4.runtime.Lexer; +import org.antlr.v4.runtime.RuleContext; +import org.antlr.v4.runtime.atn.ATN; +import org.antlr.v4.runtime.atn.ATNSimulator; +import org.antlr.v4.runtime.atn.LexerATNSimulator; +import org.antlr.v4.runtime.atn.PredictionContextCache; import org.antlr.v4.runtime.dfa.DFA; -import org.antlr.v4.runtime.misc.*; @SuppressWarnings({"all", "warnings", "unchecked", "unused", "cast"}) public class SELECTLexer extends Lexer { @@ -16,7 +17,7 @@ public class SELECTLexer extends Lexer { public static final int T__16=1, T__15=2, T__14=3, T__13=4, T__12=5, T__11=6, T__10=7, T__9=8, T__8=9, T__7=10, T__6=11, T__5=12, T__4=13, T__3=14, T__2=15, T__1=16, - T__0=17, COLUMNNAME=18, TABLENAME=19, ID=20, ID_LETTER=21; + T__0=17, ID=18, WS=19; public static String[] modeNames = { "DEFAULT_MODE" }; @@ -25,12 +26,12 @@ public class SELECTLexer extends Lexer { "", "'AS'", "'DISTINCT'", "'AND'", "'IS'", "'ALL'", "')'", "','", "'OR'", "'*'", "'WHERE'", "'('", "'FROM'", "'TRUE'", "'UNKNOWN'", "'NOT'", "'SELECT'", - "'FALSE'", "COLUMNNAME", "TABLENAME", "ID", "ID_LETTER" + "'FALSE'", "ID", "WS" }; public static final String[] ruleNames = { "T__16", "T__15", "T__14", "T__13", "T__12", "T__11", "T__10", "T__9", "T__8", "T__7", "T__6", "T__5", "T__4", "T__3", "T__2", "T__1", "T__0", - "COLUMNNAME", "TABLENAME", "ID", "ID_LETTER", "DIGIT" + "ID", "ID_LETTER", "DIGIT", "WS" }; @@ -54,43 +55,55 @@ public SELECTLexer(CharStream input) { @Override public ATN getATN() { return _ATN; } + @Override + public void action(RuleContext _localctx, int ruleIndex, int actionIndex) { + switch (ruleIndex) { + case 20: WS_action((RuleContext)_localctx, actionIndex); break; + } + } + private void WS_action(RuleContext _localctx, int actionIndex) { + switch (actionIndex) { + case 0: skip(); break; + } + } + public static final String _serializedATN = - "\3\uacf5\uee8c\u4f5d\u8b0d\u4a45\u78bd\u1b2f\u3378\2\27\u008b\b\1\4\2"+ + "\3\uacf5\uee8c\u4f5d\u8b0d\u4a45\u78bd\u1b2f\u3378\2\25\u008b\b\1\4\2"+ "\t\2\4\3\t\3\4\4\t\4\4\5\t\5\4\6\t\6\4\7\t\7\4\b\t\b\4\t\t\t\4\n\t\n\4"+ "\13\t\13\4\f\t\f\4\r\t\r\4\16\t\16\4\17\t\17\4\20\t\20\4\21\t\21\4\22"+ - "\t\22\4\23\t\23\4\24\t\24\4\25\t\25\4\26\t\26\4\27\t\27\3\2\3\2\3\2\3"+ - "\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\4\3\4\3\4\3\4\3\5\3\5\3\5\3\6\3\6"+ - "\3\6\3\6\3\7\3\7\3\b\3\b\3\t\3\t\3\t\3\n\3\n\3\13\3\13\3\13\3\13\3\13"+ - "\3\13\3\f\3\f\3\r\3\r\3\r\3\r\3\r\3\16\3\16\3\16\3\16\3\16\3\17\3\17\3"+ - "\17\3\17\3\17\3\17\3\17\3\17\3\20\3\20\3\20\3\20\3\21\3\21\3\21\3\21\3"+ - "\21\3\21\3\21\3\22\3\22\3\22\3\22\3\22\3\22\3\23\3\23\3\24\3\24\3\25\3"+ - "\25\3\25\7\25\u0082\n\25\f\25\16\25\u0085\13\25\3\26\5\26\u0088\n\26\3"+ - "\27\3\27\2\30\3\3\1\5\4\1\7\5\1\t\6\1\13\7\1\r\b\1\17\t\1\21\n\1\23\13"+ - "\1\25\f\1\27\r\1\31\16\1\33\17\1\35\20\1\37\21\1!\22\1#\23\1%\24\1\'\25"+ - "\1)\26\1+\27\1-\2\1\3\2\4\7\2CC\\\\aacc||\3\2\62;\u008b\2\3\3\2\2\2\2"+ + "\t\22\4\23\t\23\4\24\t\24\4\25\t\25\4\26\t\26\3\2\3\2\3\2\3\3\3\3\3\3"+ + "\3\3\3\3\3\3\3\3\3\3\3\3\3\4\3\4\3\4\3\4\3\5\3\5\3\5\3\6\3\6\3\6\3\6\3"+ + "\7\3\7\3\b\3\b\3\t\3\t\3\t\3\n\3\n\3\13\3\13\3\13\3\13\3\13\3\13\3\f\3"+ + "\f\3\r\3\r\3\r\3\r\3\r\3\16\3\16\3\16\3\16\3\16\3\17\3\17\3\17\3\17\3"+ + "\17\3\17\3\17\3\17\3\20\3\20\3\20\3\20\3\21\3\21\3\21\3\21\3\21\3\21\3"+ + "\21\3\22\3\22\3\22\3\22\3\22\3\22\3\23\3\23\3\23\7\23|\n\23\f\23\16\23"+ + "\177\13\23\3\24\3\24\3\25\3\25\3\26\6\26\u0086\n\26\r\26\16\26\u0087\3"+ + "\26\3\26\2\27\3\3\1\5\4\1\7\5\1\t\6\1\13\7\1\r\b\1\17\t\1\21\n\1\23\13"+ + "\1\25\f\1\27\r\1\31\16\1\33\17\1\35\20\1\37\21\1!\22\1#\23\1%\24\1\'\2"+ + "\1)\2\1+\25\2\3\2\4\5\2C\\aac|\5\2\13\f\17\17\"\"\u008b\2\3\3\2\2\2\2"+ "\5\3\2\2\2\2\7\3\2\2\2\2\t\3\2\2\2\2\13\3\2\2\2\2\r\3\2\2\2\2\17\3\2\2"+ "\2\2\21\3\2\2\2\2\23\3\2\2\2\2\25\3\2\2\2\2\27\3\2\2\2\2\31\3\2\2\2\2"+ "\33\3\2\2\2\2\35\3\2\2\2\2\37\3\2\2\2\2!\3\2\2\2\2#\3\2\2\2\2%\3\2\2\2"+ - "\2\'\3\2\2\2\2)\3\2\2\2\2+\3\2\2\2\3/\3\2\2\2\5\62\3\2\2\2\7;\3\2\2\2"+ - "\t?\3\2\2\2\13B\3\2\2\2\rF\3\2\2\2\17H\3\2\2\2\21J\3\2\2\2\23M\3\2\2\2"+ - "\25O\3\2\2\2\27U\3\2\2\2\31W\3\2\2\2\33\\\3\2\2\2\35a\3\2\2\2\37i\3\2"+ - "\2\2!m\3\2\2\2#t\3\2\2\2%z\3\2\2\2\'|\3\2\2\2)~\3\2\2\2+\u0087\3\2\2\2"+ - "-\u0089\3\2\2\2/\60\7C\2\2\60\61\7U\2\2\61\4\3\2\2\2\62\63\7F\2\2\63\64"+ - "\7K\2\2\64\65\7U\2\2\65\66\7V\2\2\66\67\7K\2\2\678\7P\2\289\7E\2\29:\7"+ - "V\2\2:\6\3\2\2\2;<\7C\2\2<=\7P\2\2=>\7F\2\2>\b\3\2\2\2?@\7K\2\2@A\7U\2"+ - "\2A\n\3\2\2\2BC\7C\2\2CD\7N\2\2DE\7N\2\2E\f\3\2\2\2FG\7+\2\2G\16\3\2\2"+ - "\2HI\7.\2\2I\20\3\2\2\2JK\7Q\2\2KL\7T\2\2L\22\3\2\2\2MN\7,\2\2N\24\3\2"+ - "\2\2OP\7Y\2\2PQ\7J\2\2QR\7G\2\2RS\7T\2\2ST\7G\2\2T\26\3\2\2\2UV\7*\2\2"+ - "V\30\3\2\2\2WX\7H\2\2XY\7T\2\2YZ\7Q\2\2Z[\7O\2\2[\32\3\2\2\2\\]\7V\2\2"+ - "]^\7T\2\2^_\7W\2\2_`\7G\2\2`\34\3\2\2\2ab\7W\2\2bc\7P\2\2cd\7M\2\2de\7"+ - "P\2\2ef\7Q\2\2fg\7Y\2\2gh\7P\2\2h\36\3\2\2\2ij\7P\2\2jk\7Q\2\2kl\7V\2"+ - "\2l \3\2\2\2mn\7U\2\2no\7G\2\2op\7N\2\2pq\7G\2\2qr\7E\2\2rs\7V\2\2s\""+ - "\3\2\2\2tu\7H\2\2uv\7C\2\2vw\7N\2\2wx\7U\2\2xy\7G\2\2y$\3\2\2\2z{\5)\25"+ - "\2{&\3\2\2\2|}\5)\25\2}(\3\2\2\2~\u0083\5+\26\2\177\u0082\5+\26\2\u0080"+ - "\u0082\5-\27\2\u0081\177\3\2\2\2\u0081\u0080\3\2\2\2\u0082\u0085\3\2\2"+ - "\2\u0083\u0081\3\2\2\2\u0083\u0084\3\2\2\2\u0084*\3\2\2\2\u0085\u0083"+ - "\3\2\2\2\u0086\u0088\t\2\2\2\u0087\u0086\3\2\2\2\u0088,\3\2\2\2\u0089"+ - "\u008a\t\3\2\2\u008a.\3\2\2\2\6\2\u0081\u0083\u0087"; + "\2+\3\2\2\2\3-\3\2\2\2\5\60\3\2\2\2\79\3\2\2\2\t=\3\2\2\2\13@\3\2\2\2"+ + "\rD\3\2\2\2\17F\3\2\2\2\21H\3\2\2\2\23K\3\2\2\2\25M\3\2\2\2\27S\3\2\2"+ + "\2\31U\3\2\2\2\33Z\3\2\2\2\35_\3\2\2\2\37g\3\2\2\2!k\3\2\2\2#r\3\2\2\2"+ + "%x\3\2\2\2\'\u0080\3\2\2\2)\u0082\3\2\2\2+\u0085\3\2\2\2-.\7C\2\2./\7"+ + "U\2\2/\4\3\2\2\2\60\61\7F\2\2\61\62\7K\2\2\62\63\7U\2\2\63\64\7V\2\2\64"+ + "\65\7K\2\2\65\66\7P\2\2\66\67\7E\2\2\678\7V\2\28\6\3\2\2\29:\7C\2\2:;"+ + "\7P\2\2;<\7F\2\2<\b\3\2\2\2=>\7K\2\2>?\7U\2\2?\n\3\2\2\2@A\7C\2\2AB\7"+ + "N\2\2BC\7N\2\2C\f\3\2\2\2DE\7+\2\2E\16\3\2\2\2FG\7.\2\2G\20\3\2\2\2HI"+ + "\7Q\2\2IJ\7T\2\2J\22\3\2\2\2KL\7,\2\2L\24\3\2\2\2MN\7Y\2\2NO\7J\2\2OP"+ + "\7G\2\2PQ\7T\2\2QR\7G\2\2R\26\3\2\2\2ST\7*\2\2T\30\3\2\2\2UV\7H\2\2VW"+ + "\7T\2\2WX\7Q\2\2XY\7O\2\2Y\32\3\2\2\2Z[\7V\2\2[\\\7T\2\2\\]\7W\2\2]^\7"+ + "G\2\2^\34\3\2\2\2_`\7W\2\2`a\7P\2\2ab\7M\2\2bc\7P\2\2cd\7Q\2\2de\7Y\2"+ + "\2ef\7P\2\2f\36\3\2\2\2gh\7P\2\2hi\7Q\2\2ij\7V\2\2j \3\2\2\2kl\7U\2\2"+ + "lm\7G\2\2mn\7N\2\2no\7G\2\2op\7E\2\2pq\7V\2\2q\"\3\2\2\2rs\7H\2\2st\7"+ + "C\2\2tu\7N\2\2uv\7U\2\2vw\7G\2\2w$\3\2\2\2x}\5\'\24\2y|\5\'\24\2z|\5)"+ + "\25\2{y\3\2\2\2{z\3\2\2\2|\177\3\2\2\2}{\3\2\2\2}~\3\2\2\2~&\3\2\2\2\177"+ + "}\3\2\2\2\u0080\u0081\t\2\2\2\u0081(\3\2\2\2\u0082\u0083\4\62;\2\u0083"+ + "*\3\2\2\2\u0084\u0086\t\3\2\2\u0085\u0084\3\2\2\2\u0086\u0087\3\2\2\2"+ + "\u0087\u0085\3\2\2\2\u0087\u0088\3\2\2\2\u0088\u0089\3\2\2\2\u0089\u008a"+ + "\b\26\2\2\u008a,\3\2\2\2\6\2{}\u0087"; public static final ATN _ATN = ATNSimulator.deserialize(_serializedATN.toCharArray()); static { diff --git a/src/com/etk/parser/SELECTLexer.tokens b/src/com/etk/parser/SELECTLexer.tokens index db84f1c..ec5aabc 100644 --- a/src/com/etk/parser/SELECTLexer.tokens +++ b/src/com/etk/parser/SELECTLexer.tokens @@ -1,6 +1,6 @@ +WS=19 T__16=1 T__15=2 -ID_LETTER=21 T__12=5 T__11=6 T__14=3 @@ -10,10 +10,8 @@ T__0=17 T__3=14 T__10=7 T__2=15 -ID=20 -COLUMNNAME=18 +ID=18 T__9=8 -TABLENAME=19 T__8=9 T__7=10 T__6=11 diff --git a/src/com/etk/parser/SELECTListener.java b/src/com/etk/parser/SELECTListener.java index e3aebba..b75cbce 100644 --- a/src/com/etk/parser/SELECTListener.java +++ b/src/com/etk/parser/SELECTListener.java @@ -1,4 +1,4 @@ -// Generated from C:\Users\Georgy\IdeaProjects\SELECTParser\src\SELECT.g4 by ANTLR 4.1 +package com.etk.parser;// Generated from C:\Users\Georgy\IdeaProjects\SELECTParser\src\SELECT.g4 by ANTLR 4.1 import org.antlr.v4.runtime.misc.NotNull; import org.antlr.v4.runtime.tree.ParseTreeListener; @@ -18,17 +18,6 @@ public interface SELECTListener extends ParseTreeListener { */ void exitWhereClause(@NotNull SELECTParser.WhereClauseContext ctx); - /** - * Enter a parse tree produced by {@link SELECTParser#tableReference}. - * @param ctx the parse tree - */ - void enterTableReference(@NotNull SELECTParser.TableReferenceContext ctx); - /** - * Exit a parse tree produced by {@link SELECTParser#tableReference}. - * @param ctx the parse tree - */ - void exitTableReference(@NotNull SELECTParser.TableReferenceContext ctx); - /** * Enter a parse tree produced by {@link SELECTParser#tableExpression}. * @param ctx the parse tree @@ -140,26 +129,26 @@ public interface SELECTListener extends ParseTreeListener { void exitBooleanTerm(@NotNull SELECTParser.BooleanTermContext ctx); /** - * Enter a parse tree produced by {@link SELECTParser#tableReferenceList}. + * Enter a parse tree produced by {@link SELECTParser#booleanPrimary}. * @param ctx the parse tree */ - void enterTableReferenceList(@NotNull SELECTParser.TableReferenceListContext ctx); + void enterBooleanPrimary(@NotNull SELECTParser.BooleanPrimaryContext ctx); /** - * Exit a parse tree produced by {@link SELECTParser#tableReferenceList}. + * Exit a parse tree produced by {@link SELECTParser#booleanPrimary}. * @param ctx the parse tree */ - void exitTableReferenceList(@NotNull SELECTParser.TableReferenceListContext ctx); + void exitBooleanPrimary(@NotNull SELECTParser.BooleanPrimaryContext ctx); /** - * Enter a parse tree produced by {@link SELECTParser#booleanPrimary}. + * Enter a parse tree produced by {@link SELECTParser#tablePrimaryAs}. * @param ctx the parse tree */ - void enterBooleanPrimary(@NotNull SELECTParser.BooleanPrimaryContext ctx); + void enterTablePrimaryAs(@NotNull SELECTParser.TablePrimaryAsContext ctx); /** - * Exit a parse tree produced by {@link SELECTParser#booleanPrimary}. + * Exit a parse tree produced by {@link SELECTParser#tablePrimaryAs}. * @param ctx the parse tree */ - void exitBooleanPrimary(@NotNull SELECTParser.BooleanPrimaryContext ctx); + void exitTablePrimaryAs(@NotNull SELECTParser.TablePrimaryAsContext ctx); /** * Enter a parse tree produced by {@link SELECTParser#derivedColumnList}. @@ -183,6 +172,17 @@ public interface SELECTListener extends ParseTreeListener { */ void exitSetQuantifier(@NotNull SELECTParser.SetQuantifierContext ctx); + /** + * Enter a parse tree produced by {@link SELECTParser#tableName}. + * @param ctx the parse tree + */ + void enterTableName(@NotNull SELECTParser.TableNameContext ctx); + /** + * Exit a parse tree produced by {@link SELECTParser#tableName}. + * @param ctx the parse tree + */ + void exitTableName(@NotNull SELECTParser.TableNameContext ctx); + /** * Enter a parse tree produced by {@link SELECTParser#parenthizedBooleanValueExpression}. * @param ctx the parse tree @@ -205,6 +205,17 @@ public interface SELECTListener extends ParseTreeListener { */ void exitSearchCondition(@NotNull SELECTParser.SearchConditionContext ctx); + /** + * Enter a parse tree produced by {@link SELECTParser#columnName}. + * @param ctx the parse tree + */ + void enterColumnName(@NotNull SELECTParser.ColumnNameContext ctx); + /** + * Exit a parse tree produced by {@link SELECTParser#columnName}. + * @param ctx the parse tree + */ + void exitColumnName(@NotNull SELECTParser.ColumnNameContext ctx); + /** * Enter a parse tree produced by {@link SELECTParser#asClause}. * @param ctx the parse tree diff --git a/src/com/etk/parser/SELECTMain.java b/src/com/etk/parser/SELECTMain.java index baf1ed9..514f942 100644 --- a/src/com/etk/parser/SELECTMain.java +++ b/src/com/etk/parser/SELECTMain.java @@ -1,10 +1,4 @@ -import org.antlr.v4.runtime.ANTLRInputStream; -import org.antlr.v4.runtime.CommonTokenStream; -import org.antlr.v4.runtime.tree.ParseTree; -import org.antlr.v4.runtime.tree.ParseTreeWalker; - -import java.io.FileInputStream; -import java.io.InputStream; +package com.etk.parser; /** * Created with IntelliJ IDEA. @@ -16,23 +10,14 @@ public class SELECTMain { public static void main(String[] args) throws Exception { - String inputFile = null; - if ( args.length>0 ) inputFile = args[0]; - InputStream is = System.in; - if ( inputFile!=null ) { - is = new FileInputStream(inputFile); - } - ANTLRInputStream input = new ANTLRInputStream(is); - SELECTLexer lexer = new SELECTLexer(input); - CommonTokenStream tokens = new CommonTokenStream(lexer); - SELECTParser parser = new SELECTParser(tokens); - parser.setBuildParseTree(true); - ParseTree tree = parser.selectStmnt(); + SelectQueryToObject selectQueryToObject = new SelectQueryToObject(args); + SelectObject selectObject = selectQueryToObject.getSelectObject(); + for(String columnName : selectObject.getColumnNames()){ + System.out.println("Column: " + columnName); + } - /* ParseTreeWalker walker = new ParseTreeWalker(); - XMLEmitter converter = new XMLEmitter(); - walker.walk(converter, tree); - System.out.println(converter.getXML(tree)); - */ + for(String tableName : selectObject.getTableNames()){ + System.out.println("Table: " + tableName); + } } } diff --git a/src/com/etk/parser/SELECTParser.java b/src/com/etk/parser/SELECTParser.java index 212788f..381f963 100644 --- a/src/com/etk/parser/SELECTParser.java +++ b/src/com/etk/parser/SELECTParser.java @@ -1,12 +1,15 @@ -// Generated from C:\Users\Georgy\IdeaProjects\SELECTParser\src\SELECT.g4 by ANTLR 4.1 -import org.antlr.v4.runtime.atn.*; -import org.antlr.v4.runtime.dfa.DFA; +package com.etk.parser;// Generated from C:\Users\Georgy\IdeaProjects\SELECTParser\src\SELECT.g4 by ANTLR 4.1 + import org.antlr.v4.runtime.*; -import org.antlr.v4.runtime.misc.*; -import org.antlr.v4.runtime.tree.*; +import org.antlr.v4.runtime.atn.ATN; +import org.antlr.v4.runtime.atn.ATNSimulator; +import org.antlr.v4.runtime.atn.ParserATNSimulator; +import org.antlr.v4.runtime.atn.PredictionContextCache; +import org.antlr.v4.runtime.dfa.DFA; +import org.antlr.v4.runtime.tree.ParseTreeListener; +import org.antlr.v4.runtime.tree.TerminalNode; + import java.util.List; -import java.util.Iterator; -import java.util.ArrayList; @SuppressWarnings({"all", "warnings", "unchecked", "unused", "cast"}) public class SELECTParser extends Parser { @@ -16,26 +19,27 @@ public class SELECTParser extends Parser { public static final int T__16=1, T__15=2, T__14=3, T__13=4, T__12=5, T__11=6, T__10=7, T__9=8, T__8=9, T__7=10, T__6=11, T__5=12, T__4=13, T__3=14, T__2=15, T__1=16, - T__0=17, COLUMNNAME=18, TABLENAME=19, ID=20, ID_LETTER=21; + T__0=17, ID=18, WS=19; public static final String[] tokenNames = { "", "'AS'", "'DISTINCT'", "'AND'", "'IS'", "'ALL'", "')'", "','", "'OR'", "'*'", "'WHERE'", "'('", "'FROM'", "'TRUE'", "'UNKNOWN'", "'NOT'", - "'SELECT'", "'FALSE'", "COLUMNNAME", "TABLENAME", "ID", "ID_LETTER" + "'SELECT'", "'FALSE'", "ID", "WS" }; public static final int RULE_selectStmnt = 0, RULE_querySpecification = 1, RULE_setQuantifier = 2, RULE_selectList = 3, RULE_derivedColumn = 4, RULE_asClause = 5, RULE_tableExpression = 6, - RULE_fromClause = 7, RULE_tableReferenceList = 8, RULE_tableReference = 9, - RULE_tablePrimary = 10, RULE_derivedColumnList = 11, RULE_whereClause = 12, - RULE_searchCondition = 13, RULE_booleanValueExpression = 14, RULE_booleanTerm = 15, - RULE_booleanFactor = 16, RULE_booleanTest = 17, RULE_truthValue = 18, - RULE_booleanPrimary = 19, RULE_booleanPredicand = 20, RULE_parenthizedBooleanValueExpression = 21; + RULE_fromClause = 7, RULE_tablePrimary = 8, RULE_tablePrimaryAs = 9, RULE_derivedColumnList = 10, + RULE_whereClause = 11, RULE_searchCondition = 12, RULE_booleanValueExpression = 13, + RULE_booleanTerm = 14, RULE_booleanFactor = 15, RULE_booleanTest = 16, + RULE_truthValue = 17, RULE_booleanPrimary = 18, RULE_booleanPredicand = 19, + RULE_parenthizedBooleanValueExpression = 20, RULE_columnName = 21, RULE_tableName = 22; public static final String[] ruleNames = { "selectStmnt", "querySpecification", "setQuantifier", "selectList", "derivedColumn", - "asClause", "tableExpression", "fromClause", "tableReferenceList", "tableReference", - "tablePrimary", "derivedColumnList", "whereClause", "searchCondition", - "booleanValueExpression", "booleanTerm", "booleanFactor", "booleanTest", - "truthValue", "booleanPrimary", "booleanPredicand", "parenthizedBooleanValueExpression" + "asClause", "tableExpression", "fromClause", "tablePrimary", "tablePrimaryAs", + "derivedColumnList", "whereClause", "searchCondition", "booleanValueExpression", + "booleanTerm", "booleanFactor", "booleanTest", "truthValue", "booleanPrimary", + "booleanPredicand", "parenthizedBooleanValueExpression", "columnName", + "tableName" }; @Override @@ -78,8 +82,8 @@ public final SelectStmntContext selectStmnt() throws RecognitionException { try { enterOuterAlt(_localctx, 1); { - setState(44); match(16); - setState(45); querySpecification(); + setState(46); match(16); + setState(47); querySpecification(); } } catch (RecognitionException re) { @@ -124,16 +128,16 @@ public final QuerySpecificationContext querySpecification() throws RecognitionEx try { enterOuterAlt(_localctx, 1); { - setState(48); + setState(50); _la = _input.LA(1); if (_la==2 || _la==5) { { - setState(47); setQuantifier(); + setState(49); setQuantifier(); } } - setState(50); selectList(); - setState(51); tableExpression(); + setState(52); selectList(); + setState(53); tableExpression(); } } catch (RecognitionException re) { @@ -169,7 +173,7 @@ public final SetQuantifierContext setQuantifier() throws RecognitionException { try { enterOuterAlt(_localctx, 1); { - setState(53); + setState(55); _la = _input.LA(1); if ( !(_la==2 || _la==5) ) { _errHandler.recoverInline(this); @@ -214,29 +218,29 @@ public final SelectListContext selectList() throws RecognitionException { enterRule(_localctx, 6, RULE_selectList); int _la; try { - setState(64); + setState(66); switch (_input.LA(1)) { case 9: enterOuterAlt(_localctx, 1); { - setState(55); match(9); + setState(57); match(9); } break; - case COLUMNNAME: + case ID: enterOuterAlt(_localctx, 2); { - setState(56); derivedColumn(); - setState(61); + setState(58); derivedColumn(); + setState(63); _errHandler.sync(this); _la = _input.LA(1); while (_la==7) { { { - setState(57); match(7); - setState(58); derivedColumn(); + setState(59); match(7); + setState(60); derivedColumn(); } } - setState(63); + setState(65); _errHandler.sync(this); _la = _input.LA(1); } @@ -258,10 +262,12 @@ public final SelectListContext selectList() throws RecognitionException { } public static class DerivedColumnContext extends ParserRuleContext { - public TerminalNode COLUMNNAME() { return getToken(SELECTParser.COLUMNNAME, 0); } public AsClauseContext asClause() { return getRuleContext(AsClauseContext.class,0); } + public ColumnNameContext columnName() { + return getRuleContext(ColumnNameContext.class,0); + } public DerivedColumnContext(ParserRuleContext parent, int invokingState) { super(parent, invokingState); } @@ -283,12 +289,12 @@ public final DerivedColumnContext derivedColumn() throws RecognitionException { try { enterOuterAlt(_localctx, 1); { - setState(66); match(COLUMNNAME); - setState(68); + setState(68); columnName(); + setState(70); _la = _input.LA(1); if (_la==1) { { - setState(67); asClause(); + setState(69); asClause(); } } @@ -306,7 +312,9 @@ public final DerivedColumnContext derivedColumn() throws RecognitionException { } public static class AsClauseContext extends ParserRuleContext { - public TerminalNode COLUMNNAME() { return getToken(SELECTParser.COLUMNNAME, 0); } + public ColumnNameContext columnName() { + return getRuleContext(ColumnNameContext.class,0); + } public AsClauseContext(ParserRuleContext parent, int invokingState) { super(parent, invokingState); } @@ -327,8 +335,8 @@ public final AsClauseContext asClause() throws RecognitionException { try { enterOuterAlt(_localctx, 1); { - setState(70); match(1); - setState(71); match(COLUMNNAME); + setState(72); match(1); + setState(73); columnName(); } } catch (RecognitionException re) { @@ -366,7 +374,7 @@ public final TableExpressionContext tableExpression() throws RecognitionExceptio try { enterOuterAlt(_localctx, 1); { - setState(73); fromClause(); + setState(75); fromClause(); } } catch (RecognitionException re) { @@ -381,8 +389,11 @@ public final TableExpressionContext tableExpression() throws RecognitionExceptio } public static class FromClauseContext extends ParserRuleContext { - public TableReferenceListContext tableReferenceList() { - return getRuleContext(TableReferenceListContext.class,0); + public List tablePrimary() { + return getRuleContexts(TablePrimaryContext.class); + } + public TablePrimaryContext tablePrimary(int i) { + return getRuleContext(TablePrimaryContext.class,i); } public FromClauseContext(ParserRuleContext parent, int invokingState) { super(parent, invokingState); @@ -401,53 +412,12 @@ public void exitRule(ParseTreeListener listener) { public final FromClauseContext fromClause() throws RecognitionException { FromClauseContext _localctx = new FromClauseContext(_ctx, getState()); enterRule(_localctx, 14, RULE_fromClause); - try { - enterOuterAlt(_localctx, 1); - { - setState(75); match(12); - setState(76); tableReferenceList(); - } - } - catch (RecognitionException re) { - _localctx.exception = re; - _errHandler.reportError(this, re); - _errHandler.recover(this, re); - } - finally { - exitRule(); - } - return _localctx; - } - - public static class TableReferenceListContext extends ParserRuleContext { - public List tableReference() { - return getRuleContexts(TableReferenceContext.class); - } - public TableReferenceContext tableReference(int i) { - return getRuleContext(TableReferenceContext.class,i); - } - public TableReferenceListContext(ParserRuleContext parent, int invokingState) { - super(parent, invokingState); - } - @Override public int getRuleIndex() { return RULE_tableReferenceList; } - @Override - public void enterRule(ParseTreeListener listener) { - if ( listener instanceof SELECTListener ) ((SELECTListener)listener).enterTableReferenceList(this); - } - @Override - public void exitRule(ParseTreeListener listener) { - if ( listener instanceof SELECTListener ) ((SELECTListener)listener).exitTableReferenceList(this); - } - } - - public final TableReferenceListContext tableReferenceList() throws RecognitionException { - TableReferenceListContext _localctx = new TableReferenceListContext(_ctx, getState()); - enterRule(_localctx, 16, RULE_tableReferenceList); int _la; try { enterOuterAlt(_localctx, 1); { - setState(78); tableReference(); + setState(77); match(12); + setState(78); tablePrimary(); setState(83); _errHandler.sync(this); _la = _input.LA(1); @@ -455,7 +425,7 @@ public final TableReferenceListContext tableReferenceList() throws RecognitionEx { { setState(79); match(7); - setState(80); tableReference(); + setState(80); tablePrimary(); } } setState(85); @@ -475,31 +445,44 @@ public final TableReferenceListContext tableReferenceList() throws RecognitionEx return _localctx; } - public static class TableReferenceContext extends ParserRuleContext { - public TablePrimaryContext tablePrimary() { - return getRuleContext(TablePrimaryContext.class,0); + public static class TablePrimaryContext extends ParserRuleContext { + public TableNameContext tableName() { + return getRuleContext(TableNameContext.class,0); + } + public TablePrimaryAsContext tablePrimaryAs() { + return getRuleContext(TablePrimaryAsContext.class,0); } - public TableReferenceContext(ParserRuleContext parent, int invokingState) { + public TablePrimaryContext(ParserRuleContext parent, int invokingState) { super(parent, invokingState); } - @Override public int getRuleIndex() { return RULE_tableReference; } + @Override public int getRuleIndex() { return RULE_tablePrimary; } @Override public void enterRule(ParseTreeListener listener) { - if ( listener instanceof SELECTListener ) ((SELECTListener)listener).enterTableReference(this); + if ( listener instanceof SELECTListener ) ((SELECTListener)listener).enterTablePrimary(this); } @Override public void exitRule(ParseTreeListener listener) { - if ( listener instanceof SELECTListener ) ((SELECTListener)listener).exitTableReference(this); + if ( listener instanceof SELECTListener ) ((SELECTListener)listener).exitTablePrimary(this); } } - public final TableReferenceContext tableReference() throws RecognitionException { - TableReferenceContext _localctx = new TableReferenceContext(_ctx, getState()); - enterRule(_localctx, 18, RULE_tableReference); + public final TablePrimaryContext tablePrimary() throws RecognitionException { + TablePrimaryContext _localctx = new TablePrimaryContext(_ctx, getState()); + enterRule(_localctx, 16, RULE_tablePrimary); + int _la; try { enterOuterAlt(_localctx, 1); { - setState(86); tablePrimary(); + setState(86); tableName(); + setState(89); + _la = _input.LA(1); + if (_la==1) { + { + setState(87); match(1); + setState(88); tablePrimaryAs(); + } + } + } } catch (RecognitionException re) { @@ -513,59 +496,42 @@ public final TableReferenceContext tableReference() throws RecognitionException return _localctx; } - public static class TablePrimaryContext extends ParserRuleContext { + public static class TablePrimaryAsContext extends ParserRuleContext { public DerivedColumnListContext derivedColumnList() { return getRuleContext(DerivedColumnListContext.class,0); } - public List TABLENAME() { return getTokens(SELECTParser.TABLENAME); } - public TerminalNode TABLENAME(int i) { - return getToken(SELECTParser.TABLENAME, i); + public TableNameContext tableName() { + return getRuleContext(TableNameContext.class,0); } - public TablePrimaryContext(ParserRuleContext parent, int invokingState) { + public TablePrimaryAsContext(ParserRuleContext parent, int invokingState) { super(parent, invokingState); } - @Override public int getRuleIndex() { return RULE_tablePrimary; } + @Override public int getRuleIndex() { return RULE_tablePrimaryAs; } @Override public void enterRule(ParseTreeListener listener) { - if ( listener instanceof SELECTListener ) ((SELECTListener)listener).enterTablePrimary(this); + if ( listener instanceof SELECTListener ) ((SELECTListener)listener).enterTablePrimaryAs(this); } @Override public void exitRule(ParseTreeListener listener) { - if ( listener instanceof SELECTListener ) ((SELECTListener)listener).exitTablePrimary(this); + if ( listener instanceof SELECTListener ) ((SELECTListener)listener).exitTablePrimaryAs(this); } } - public final TablePrimaryContext tablePrimary() throws RecognitionException { - TablePrimaryContext _localctx = new TablePrimaryContext(_ctx, getState()); - enterRule(_localctx, 20, RULE_tablePrimary); + public final TablePrimaryAsContext tablePrimaryAs() throws RecognitionException { + TablePrimaryAsContext _localctx = new TablePrimaryAsContext(_ctx, getState()); + enterRule(_localctx, 18, RULE_tablePrimaryAs); int _la; try { enterOuterAlt(_localctx, 1); { - setState(88); match(TABLENAME); - setState(99); + setState(91); tableName(); + setState(96); _la = _input.LA(1); - if (_la==1 || _la==TABLENAME) { + if (_la==11) { { - setState(90); - _la = _input.LA(1); - if (_la==1) { - { - setState(89); match(1); - } - } - - setState(92); match(TABLENAME); - setState(97); - _la = _input.LA(1); - if (_la==11) { - { - setState(93); match(11); - setState(94); derivedColumnList(); - setState(95); match(6); - } - } - + setState(92); match(11); + setState(93); derivedColumnList(); + setState(94); match(6); } } @@ -583,10 +549,12 @@ public final TablePrimaryContext tablePrimary() throws RecognitionException { } public static class DerivedColumnListContext extends ParserRuleContext { - public TerminalNode COLUMNNAME(int i) { - return getToken(SELECTParser.COLUMNNAME, i); + public ColumnNameContext columnName(int i) { + return getRuleContext(ColumnNameContext.class,i); + } + public List columnName() { + return getRuleContexts(ColumnNameContext.class); } - public List COLUMNNAME() { return getTokens(SELECTParser.COLUMNNAME); } public DerivedColumnListContext(ParserRuleContext parent, int invokingState) { super(parent, invokingState); } @@ -603,33 +571,26 @@ public void exitRule(ParseTreeListener listener) { public final DerivedColumnListContext derivedColumnList() throws RecognitionException { DerivedColumnListContext _localctx = new DerivedColumnListContext(_ctx, getState()); - enterRule(_localctx, 22, RULE_derivedColumnList); + enterRule(_localctx, 20, RULE_derivedColumnList); int _la; try { enterOuterAlt(_localctx, 1); { - setState(101); match(COLUMNNAME); - setState(108); + setState(98); columnName(); + setState(103); + _errHandler.sync(this); _la = _input.LA(1); - if (_la==7) { + while (_la==7) { + { { - setState(104); + setState(99); match(7); + setState(100); columnName(); + } + } + setState(105); _errHandler.sync(this); _la = _input.LA(1); - do { - { - { - setState(102); match(7); - setState(103); match(COLUMNNAME); - } - } - setState(106); - _errHandler.sync(this); - _la = _input.LA(1); - } while ( _la==7 ); - } } - } } catch (RecognitionException re) { @@ -663,12 +624,12 @@ public void exitRule(ParseTreeListener listener) { public final WhereClauseContext whereClause() throws RecognitionException { WhereClauseContext _localctx = new WhereClauseContext(_ctx, getState()); - enterRule(_localctx, 24, RULE_whereClause); + enterRule(_localctx, 22, RULE_whereClause); try { enterOuterAlt(_localctx, 1); { - setState(110); match(10); - setState(111); searchCondition(); + setState(106); match(10); + setState(107); searchCondition(); } } catch (RecognitionException re) { @@ -702,11 +663,11 @@ public void exitRule(ParseTreeListener listener) { public final SearchConditionContext searchCondition() throws RecognitionException { SearchConditionContext _localctx = new SearchConditionContext(_ctx, getState()); - enterRule(_localctx, 26, RULE_searchCondition); + enterRule(_localctx, 24, RULE_searchCondition); try { enterOuterAlt(_localctx, 1); { - setState(113); booleanValueExpression(0); + setState(109); booleanValueExpression(0); } } catch (RecognitionException re) { @@ -749,19 +710,19 @@ public final BooleanValueExpressionContext booleanValueExpression(int _p) throws int _parentState = getState(); BooleanValueExpressionContext _localctx = new BooleanValueExpressionContext(_ctx, _parentState, _p); BooleanValueExpressionContext _prevctx = _localctx; - int _startState = 28; + int _startState = 26; enterRecursionRule(_localctx, RULE_booleanValueExpression); try { int _alt; enterOuterAlt(_localctx, 1); { { - setState(116); booleanTerm(0); + setState(112); booleanTerm(0); } _ctx.stop = _input.LT(-1); - setState(123); + setState(119); _errHandler.sync(this); - _alt = getInterpreter().adaptivePredict(_input,10,_ctx); + _alt = getInterpreter().adaptivePredict(_input,8,_ctx); while ( _alt!=2 && _alt!=-1 ) { if ( _alt==1 ) { if ( _parseListeners!=null ) triggerExitRuleEvent(); @@ -770,16 +731,16 @@ public final BooleanValueExpressionContext booleanValueExpression(int _p) throws { _localctx = new BooleanValueExpressionContext(_parentctx, _parentState, _p); pushNewRecursionContext(_localctx, _startState, RULE_booleanValueExpression); - setState(118); + setState(114); if (!(1 >= _localctx._p)) throw new FailedPredicateException(this, "1 >= $_p"); - setState(119); match(8); - setState(120); booleanTerm(0); + setState(115); match(8); + setState(116); booleanTerm(0); } } } - setState(125); + setState(121); _errHandler.sync(this); - _alt = getInterpreter().adaptivePredict(_input,10,_ctx); + _alt = getInterpreter().adaptivePredict(_input,8,_ctx); } } } @@ -823,19 +784,19 @@ public final BooleanTermContext booleanTerm(int _p) throws RecognitionException int _parentState = getState(); BooleanTermContext _localctx = new BooleanTermContext(_ctx, _parentState, _p); BooleanTermContext _prevctx = _localctx; - int _startState = 30; + int _startState = 28; enterRecursionRule(_localctx, RULE_booleanTerm); try { int _alt; enterOuterAlt(_localctx, 1); { { - setState(127); booleanFactor(); + setState(123); booleanFactor(); } _ctx.stop = _input.LT(-1); - setState(134); + setState(130); _errHandler.sync(this); - _alt = getInterpreter().adaptivePredict(_input,11,_ctx); + _alt = getInterpreter().adaptivePredict(_input,9,_ctx); while ( _alt!=2 && _alt!=-1 ) { if ( _alt==1 ) { if ( _parseListeners!=null ) triggerExitRuleEvent(); @@ -844,16 +805,16 @@ public final BooleanTermContext booleanTerm(int _p) throws RecognitionException { _localctx = new BooleanTermContext(_parentctx, _parentState, _p); pushNewRecursionContext(_localctx, _startState, RULE_booleanTerm); - setState(129); + setState(125); if (!(1 >= _localctx._p)) throw new FailedPredicateException(this, "1 >= $_p"); - setState(130); match(3); - setState(131); booleanFactor(); + setState(126); match(3); + setState(127); booleanFactor(); } } } - setState(136); + setState(132); _errHandler.sync(this); - _alt = getInterpreter().adaptivePredict(_input,11,_ctx); + _alt = getInterpreter().adaptivePredict(_input,9,_ctx); } } } @@ -888,20 +849,20 @@ public void exitRule(ParseTreeListener listener) { public final BooleanFactorContext booleanFactor() throws RecognitionException { BooleanFactorContext _localctx = new BooleanFactorContext(_ctx, getState()); - enterRule(_localctx, 32, RULE_booleanFactor); + enterRule(_localctx, 30, RULE_booleanFactor); int _la; try { enterOuterAlt(_localctx, 1); { - setState(138); + setState(134); _la = _input.LA(1); if (_la==15) { { - setState(137); match(15); + setState(133); match(15); } } - setState(140); booleanTest(); + setState(136); booleanTest(); } } catch (RecognitionException re) { @@ -938,26 +899,26 @@ public void exitRule(ParseTreeListener listener) { public final BooleanTestContext booleanTest() throws RecognitionException { BooleanTestContext _localctx = new BooleanTestContext(_ctx, getState()); - enterRule(_localctx, 34, RULE_booleanTest); + enterRule(_localctx, 32, RULE_booleanTest); int _la; try { enterOuterAlt(_localctx, 1); { - setState(142); booleanPrimary(); - setState(148); - switch ( getInterpreter().adaptivePredict(_input,14,_ctx) ) { + setState(138); booleanPrimary(); + setState(144); + switch ( getInterpreter().adaptivePredict(_input,12,_ctx) ) { case 1: { - setState(143); match(4); - setState(145); + setState(139); match(4); + setState(141); _la = _input.LA(1); if (_la==15) { { - setState(144); match(15); + setState(140); match(15); } } - setState(147); truthValue(); + setState(143); truthValue(); } break; } @@ -991,12 +952,12 @@ public void exitRule(ParseTreeListener listener) { public final TruthValueContext truthValue() throws RecognitionException { TruthValueContext _localctx = new TruthValueContext(_ctx, getState()); - enterRule(_localctx, 36, RULE_truthValue); + enterRule(_localctx, 34, RULE_truthValue); int _la; try { enterOuterAlt(_localctx, 1); { - setState(150); + setState(146); _la = _input.LA(1); if ( !((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << 13) | (1L << 14) | (1L << 17))) != 0)) ) { _errHandler.recoverInline(this); @@ -1035,11 +996,11 @@ public void exitRule(ParseTreeListener listener) { public final BooleanPrimaryContext booleanPrimary() throws RecognitionException { BooleanPrimaryContext _localctx = new BooleanPrimaryContext(_ctx, getState()); - enterRule(_localctx, 38, RULE_booleanPrimary); + enterRule(_localctx, 36, RULE_booleanPrimary); try { enterOuterAlt(_localctx, 1); { - setState(152); booleanPredicand(); + setState(148); booleanPredicand(); } } catch (RecognitionException re) { @@ -1073,11 +1034,11 @@ public void exitRule(ParseTreeListener listener) { public final BooleanPredicandContext booleanPredicand() throws RecognitionException { BooleanPredicandContext _localctx = new BooleanPredicandContext(_ctx, getState()); - enterRule(_localctx, 40, RULE_booleanPredicand); + enterRule(_localctx, 38, RULE_booleanPredicand); try { enterOuterAlt(_localctx, 1); { - setState(154); parenthizedBooleanValueExpression(); + setState(150); parenthizedBooleanValueExpression(); } } catch (RecognitionException re) { @@ -1111,13 +1072,85 @@ public void exitRule(ParseTreeListener listener) { public final ParenthizedBooleanValueExpressionContext parenthizedBooleanValueExpression() throws RecognitionException { ParenthizedBooleanValueExpressionContext _localctx = new ParenthizedBooleanValueExpressionContext(_ctx, getState()); - enterRule(_localctx, 42, RULE_parenthizedBooleanValueExpression); + enterRule(_localctx, 40, RULE_parenthizedBooleanValueExpression); + try { + enterOuterAlt(_localctx, 1); + { + setState(152); match(11); + setState(153); booleanValueExpression(0); + setState(154); match(6); + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + public static class ColumnNameContext extends ParserRuleContext { + public TerminalNode ID() { return getToken(SELECTParser.ID, 0); } + public ColumnNameContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_columnName; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof SELECTListener ) ((SELECTListener)listener).enterColumnName(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof SELECTListener ) ((SELECTListener)listener).exitColumnName(this); + } + } + + public final ColumnNameContext columnName() throws RecognitionException { + ColumnNameContext _localctx = new ColumnNameContext(_ctx, getState()); + enterRule(_localctx, 42, RULE_columnName); + try { + enterOuterAlt(_localctx, 1); + { + setState(156); match(ID); + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + public static class TableNameContext extends ParserRuleContext { + public TerminalNode ID() { return getToken(SELECTParser.ID, 0); } + public TableNameContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_tableName; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof SELECTListener ) ((SELECTListener)listener).enterTableName(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof SELECTListener ) ((SELECTListener)listener).exitTableName(this); + } + } + + public final TableNameContext tableName() throws RecognitionException { + TableNameContext _localctx = new TableNameContext(_ctx, getState()); + enterRule(_localctx, 44, RULE_tableName); try { enterOuterAlt(_localctx, 1); { - setState(156); match(11); - setState(157); booleanValueExpression(0); - setState(158); match(6); + setState(158); match(ID); } } catch (RecognitionException re) { @@ -1133,9 +1166,9 @@ public final ParenthizedBooleanValueExpressionContext parenthizedBooleanValueExp public boolean sempred(RuleContext _localctx, int ruleIndex, int predIndex) { switch (ruleIndex) { - case 14: return booleanValueExpression_sempred((BooleanValueExpressionContext)_localctx, predIndex); + case 13: return booleanValueExpression_sempred((BooleanValueExpressionContext)_localctx, predIndex); - case 15: return booleanTerm_sempred((BooleanTermContext)_localctx, predIndex); + case 14: return booleanTerm_sempred((BooleanTermContext)_localctx, predIndex); } return true; } @@ -1153,49 +1186,49 @@ private boolean booleanTerm_sempred(BooleanTermContext _localctx, int predIndex) } public static final String _serializedATN = - "\3\uacf5\uee8c\u4f5d\u8b0d\u4a45\u78bd\u1b2f\u3378\3\27\u00a3\4\2\t\2"+ + "\3\uacf5\uee8c\u4f5d\u8b0d\u4a45\u78bd\u1b2f\u3378\3\25\u00a3\4\2\t\2"+ "\4\3\t\3\4\4\t\4\4\5\t\5\4\6\t\6\4\7\t\7\4\b\t\b\4\t\t\t\4\n\t\n\4\13"+ "\t\13\4\f\t\f\4\r\t\r\4\16\t\16\4\17\t\17\4\20\t\20\4\21\t\21\4\22\t\22"+ - "\4\23\t\23\4\24\t\24\4\25\t\25\4\26\t\26\4\27\t\27\3\2\3\2\3\2\3\3\5\3"+ - "\63\n\3\3\3\3\3\3\3\3\4\3\4\3\5\3\5\3\5\3\5\7\5>\n\5\f\5\16\5A\13\5\5"+ - "\5C\n\5\3\6\3\6\5\6G\n\6\3\7\3\7\3\7\3\b\3\b\3\t\3\t\3\t\3\n\3\n\3\n\7"+ - "\nT\n\n\f\n\16\nW\13\n\3\13\3\13\3\f\3\f\5\f]\n\f\3\f\3\f\3\f\3\f\3\f"+ - "\5\fd\n\f\5\ff\n\f\3\r\3\r\3\r\6\rk\n\r\r\r\16\rl\5\ro\n\r\3\16\3\16\3"+ - "\16\3\17\3\17\3\20\3\20\3\20\3\20\3\20\3\20\7\20|\n\20\f\20\16\20\177"+ - "\13\20\3\21\3\21\3\21\3\21\3\21\3\21\7\21\u0087\n\21\f\21\16\21\u008a"+ - "\13\21\3\22\5\22\u008d\n\22\3\22\3\22\3\23\3\23\3\23\5\23\u0094\n\23\3"+ - "\23\5\23\u0097\n\23\3\24\3\24\3\25\3\25\3\26\3\26\3\27\3\27\3\27\3\27"+ - "\3\27\2\30\2\4\6\b\n\f\16\20\22\24\26\30\32\34\36 \"$&(*,\2\4\4\2\4\4"+ - "\7\7\4\2\17\20\23\23\u009b\2.\3\2\2\2\4\62\3\2\2\2\6\67\3\2\2\2\bB\3\2"+ - "\2\2\nD\3\2\2\2\fH\3\2\2\2\16K\3\2\2\2\20M\3\2\2\2\22P\3\2\2\2\24X\3\2"+ - "\2\2\26Z\3\2\2\2\30g\3\2\2\2\32p\3\2\2\2\34s\3\2\2\2\36u\3\2\2\2 \u0080"+ - "\3\2\2\2\"\u008c\3\2\2\2$\u0090\3\2\2\2&\u0098\3\2\2\2(\u009a\3\2\2\2"+ - "*\u009c\3\2\2\2,\u009e\3\2\2\2./\7\22\2\2/\60\5\4\3\2\60\3\3\2\2\2\61"+ - "\63\5\6\4\2\62\61\3\2\2\2\62\63\3\2\2\2\63\64\3\2\2\2\64\65\5\b\5\2\65"+ - "\66\5\16\b\2\66\5\3\2\2\2\678\t\2\2\28\7\3\2\2\29C\7\13\2\2:?\5\n\6\2"+ - ";<\7\t\2\2<>\5\n\6\2=;\3\2\2\2>A\3\2\2\2?=\3\2\2\2?@\3\2\2\2@C\3\2\2\2"+ - "A?\3\2\2\2B9\3\2\2\2B:\3\2\2\2C\t\3\2\2\2DF\7\24\2\2EG\5\f\7\2FE\3\2\2"+ - "\2FG\3\2\2\2G\13\3\2\2\2HI\7\3\2\2IJ\7\24\2\2J\r\3\2\2\2KL\5\20\t\2L\17"+ - "\3\2\2\2MN\7\16\2\2NO\5\22\n\2O\21\3\2\2\2PU\5\24\13\2QR\7\t\2\2RT\5\24"+ - "\13\2SQ\3\2\2\2TW\3\2\2\2US\3\2\2\2UV\3\2\2\2V\23\3\2\2\2WU\3\2\2\2XY"+ - "\5\26\f\2Y\25\3\2\2\2Ze\7\25\2\2[]\7\3\2\2\\[\3\2\2\2\\]\3\2\2\2]^\3\2"+ - "\2\2^c\7\25\2\2_`\7\r\2\2`a\5\30\r\2ab\7\b\2\2bd\3\2\2\2c_\3\2\2\2cd\3"+ - "\2\2\2df\3\2\2\2e\\\3\2\2\2ef\3\2\2\2f\27\3\2\2\2gn\7\24\2\2hi\7\t\2\2"+ - "ik\7\24\2\2jh\3\2\2\2kl\3\2\2\2lj\3\2\2\2lm\3\2\2\2mo\3\2\2\2nj\3\2\2"+ - "\2no\3\2\2\2o\31\3\2\2\2pq\7\f\2\2qr\5\34\17\2r\33\3\2\2\2st\5\36\20\2"+ - "t\35\3\2\2\2uv\b\20\1\2vw\5 \21\2w}\3\2\2\2xy\6\20\2\3yz\7\n\2\2z|\5 "+ - "\21\2{x\3\2\2\2|\177\3\2\2\2}{\3\2\2\2}~\3\2\2\2~\37\3\2\2\2\177}\3\2"+ - "\2\2\u0080\u0081\b\21\1\2\u0081\u0082\5\"\22\2\u0082\u0088\3\2\2\2\u0083"+ - "\u0084\6\21\3\3\u0084\u0085\7\5\2\2\u0085\u0087\5\"\22\2\u0086\u0083\3"+ - "\2\2\2\u0087\u008a\3\2\2\2\u0088\u0086\3\2\2\2\u0088\u0089\3\2\2\2\u0089"+ - "!\3\2\2\2\u008a\u0088\3\2\2\2\u008b\u008d\7\21\2\2\u008c\u008b\3\2\2\2"+ - "\u008c\u008d\3\2\2\2\u008d\u008e\3\2\2\2\u008e\u008f\5$\23\2\u008f#\3"+ - "\2\2\2\u0090\u0096\5(\25\2\u0091\u0093\7\6\2\2\u0092\u0094\7\21\2\2\u0093"+ - "\u0092\3\2\2\2\u0093\u0094\3\2\2\2\u0094\u0095\3\2\2\2\u0095\u0097\5&"+ - "\24\2\u0096\u0091\3\2\2\2\u0096\u0097\3\2\2\2\u0097%\3\2\2\2\u0098\u0099"+ - "\t\3\2\2\u0099\'\3\2\2\2\u009a\u009b\5*\26\2\u009b)\3\2\2\2\u009c\u009d"+ - "\5,\27\2\u009d+\3\2\2\2\u009e\u009f\7\r\2\2\u009f\u00a0\5\36\20\2\u00a0"+ - "\u00a1\7\b\2\2\u00a1-\3\2\2\2\21\62?BFU\\celn}\u0088\u008c\u0093\u0096"; + "\4\23\t\23\4\24\t\24\4\25\t\25\4\26\t\26\4\27\t\27\4\30\t\30\3\2\3\2\3"+ + "\2\3\3\5\3\65\n\3\3\3\3\3\3\3\3\4\3\4\3\5\3\5\3\5\3\5\7\5@\n\5\f\5\16"+ + "\5C\13\5\5\5E\n\5\3\6\3\6\5\6I\n\6\3\7\3\7\3\7\3\b\3\b\3\t\3\t\3\t\3\t"+ + "\7\tT\n\t\f\t\16\tW\13\t\3\n\3\n\3\n\5\n\\\n\n\3\13\3\13\3\13\3\13\3\13"+ + "\5\13c\n\13\3\f\3\f\3\f\7\fh\n\f\f\f\16\fk\13\f\3\r\3\r\3\r\3\16\3\16"+ + "\3\17\3\17\3\17\3\17\3\17\3\17\7\17x\n\17\f\17\16\17{\13\17\3\20\3\20"+ + "\3\20\3\20\3\20\3\20\7\20\u0083\n\20\f\20\16\20\u0086\13\20\3\21\5\21"+ + "\u0089\n\21\3\21\3\21\3\22\3\22\3\22\5\22\u0090\n\22\3\22\5\22\u0093\n"+ + "\22\3\23\3\23\3\24\3\24\3\25\3\25\3\26\3\26\3\26\3\26\3\27\3\27\3\30\3"+ + "\30\3\30\2\31\2\4\6\b\n\f\16\20\22\24\26\30\32\34\36 \"$&(*,.\2\4\4\2"+ + "\4\4\7\7\4\2\17\20\23\23\u0098\2\60\3\2\2\2\4\64\3\2\2\2\69\3\2\2\2\b"+ + "D\3\2\2\2\nF\3\2\2\2\fJ\3\2\2\2\16M\3\2\2\2\20O\3\2\2\2\22X\3\2\2\2\24"+ + "]\3\2\2\2\26d\3\2\2\2\30l\3\2\2\2\32o\3\2\2\2\34q\3\2\2\2\36|\3\2\2\2"+ + " \u0088\3\2\2\2\"\u008c\3\2\2\2$\u0094\3\2\2\2&\u0096\3\2\2\2(\u0098\3"+ + "\2\2\2*\u009a\3\2\2\2,\u009e\3\2\2\2.\u00a0\3\2\2\2\60\61\7\22\2\2\61"+ + "\62\5\4\3\2\62\3\3\2\2\2\63\65\5\6\4\2\64\63\3\2\2\2\64\65\3\2\2\2\65"+ + "\66\3\2\2\2\66\67\5\b\5\2\678\5\16\b\28\5\3\2\2\29:\t\2\2\2:\7\3\2\2\2"+ + ";E\7\13\2\2\7\t\2\2>@\5\n\6\2?=\3\2\2\2@C\3\2\2\2A?\3\2\2"+ + "\2AB\3\2\2\2BE\3\2\2\2CA\3\2\2\2D;\3\2\2\2D<\3\2\2\2E\t\3\2\2\2FH\5,\27"+ + "\2GI\5\f\7\2HG\3\2\2\2HI\3\2\2\2I\13\3\2\2\2JK\7\3\2\2KL\5,\27\2L\r\3"+ + "\2\2\2MN\5\20\t\2N\17\3\2\2\2OP\7\16\2\2PU\5\22\n\2QR\7\t\2\2RT\5\22\n"+ + "\2SQ\3\2\2\2TW\3\2\2\2US\3\2\2\2UV\3\2\2\2V\21\3\2\2\2WU\3\2\2\2X[\5."+ + "\30\2YZ\7\3\2\2Z\\\5\24\13\2[Y\3\2\2\2[\\\3\2\2\2\\\23\3\2\2\2]b\5.\30"+ + "\2^_\7\r\2\2_`\5\26\f\2`a\7\b\2\2ac\3\2\2\2b^\3\2\2\2bc\3\2\2\2c\25\3"+ + "\2\2\2di\5,\27\2ef\7\t\2\2fh\5,\27\2ge\3\2\2\2hk\3\2\2\2ig\3\2\2\2ij\3"+ + "\2\2\2j\27\3\2\2\2ki\3\2\2\2lm\7\f\2\2mn\5\32\16\2n\31\3\2\2\2op\5\34"+ + "\17\2p\33\3\2\2\2qr\b\17\1\2rs\5\36\20\2sy\3\2\2\2tu\6\17\2\3uv\7\n\2"+ + "\2vx\5\36\20\2wt\3\2\2\2x{\3\2\2\2yw\3\2\2\2yz\3\2\2\2z\35\3\2\2\2{y\3"+ + "\2\2\2|}\b\20\1\2}~\5 \21\2~\u0084\3\2\2\2\177\u0080\6\20\3\3\u0080\u0081"+ + "\7\5\2\2\u0081\u0083\5 \21\2\u0082\177\3\2\2\2\u0083\u0086\3\2\2\2\u0084"+ + "\u0082\3\2\2\2\u0084\u0085\3\2\2\2\u0085\37\3\2\2\2\u0086\u0084\3\2\2"+ + "\2\u0087\u0089\7\21\2\2\u0088\u0087\3\2\2\2\u0088\u0089\3\2\2\2\u0089"+ + "\u008a\3\2\2\2\u008a\u008b\5\"\22\2\u008b!\3\2\2\2\u008c\u0092\5&\24\2"+ + "\u008d\u008f\7\6\2\2\u008e\u0090\7\21\2\2\u008f\u008e\3\2\2\2\u008f\u0090"+ + "\3\2\2\2\u0090\u0091\3\2\2\2\u0091\u0093\5$\23\2\u0092\u008d\3\2\2\2\u0092"+ + "\u0093\3\2\2\2\u0093#\3\2\2\2\u0094\u0095\t\3\2\2\u0095%\3\2\2\2\u0096"+ + "\u0097\5(\25\2\u0097\'\3\2\2\2\u0098\u0099\5*\26\2\u0099)\3\2\2\2\u009a"+ + "\u009b\7\r\2\2\u009b\u009c\5\34\17\2\u009c\u009d\7\b\2\2\u009d+\3\2\2"+ + "\2\u009e\u009f\7\24\2\2\u009f-\3\2\2\2\u00a0\u00a1\7\24\2\2\u00a1/\3\2"+ + "\2\2\17\64ADHU[biy\u0084\u0088\u008f\u0092"; public static final ATN _ATN = ATNSimulator.deserialize(_serializedATN.toCharArray()); static { diff --git a/src/com/etk/parser/SelectObject.java b/src/com/etk/parser/SelectObject.java new file mode 100644 index 0000000..b7280b7 --- /dev/null +++ b/src/com/etk/parser/SelectObject.java @@ -0,0 +1,43 @@ +package com.etk.parser; + +import java.util.ArrayList; + +/** + * Created with IntelliJ IDEA. + * User: Georgy + * Date: 18.11.13 + * Time: 21:17 + * To change this template use File | Settings | File Templates. + */ +public class SelectObject { + ArrayList columnNames; + ArrayList tableNames; + + public SelectObject(){ + + } + + public void addColumnName(String columnName){ + if(columnNames == null){ + columnNames = new ArrayList(); + } + this.columnNames.add(columnName); + } + + public ArrayList getColumnNames(){ + return this.columnNames; + } + + public void addTableName(String tableName){ + if(tableNames == null){ + tableNames = new ArrayList(); + } + this.tableNames.add(tableName); + } + + public ArrayList getTableNames(){ + return this.tableNames; + } + + +} diff --git a/src/com/etk/parser/SelectQueryToObject.java b/src/com/etk/parser/SelectQueryToObject.java new file mode 100644 index 0000000..9b96617 --- /dev/null +++ b/src/com/etk/parser/SelectQueryToObject.java @@ -0,0 +1,55 @@ +package com.etk.parser; + +import org.antlr.v4.runtime.ANTLRInputStream; +import org.antlr.v4.runtime.CommonTokenStream; +import org.antlr.v4.runtime.misc.NotNull; +import org.antlr.v4.runtime.tree.ParseTree; +import org.antlr.v4.runtime.tree.ParseTreeWalker; + +import java.io.FileInputStream; +import java.io.InputStream; + +/** + * Created with IntelliJ IDEA. + * User: Georgy + * Date: 18.11.13 + * Time: 18:29 + * To change this template use File | Settings | File Templates. + */ +public class SelectQueryToObject extends SELECTBaseListener { + + private SelectObject selectObject; + + public SelectQueryToObject(String[] args) throws Exception { + selectObject = new SelectObject(); + String inputFile = null; + if ( args.length>0 ) inputFile = args[0]; + InputStream is = System.in; + if ( inputFile!=null ) { + is = new FileInputStream(inputFile); + } + ANTLRInputStream input = new ANTLRInputStream(is); + SELECTLexer lexer = new SELECTLexer(input); + CommonTokenStream tokens = new CommonTokenStream(lexer); + SELECTParser parser = new SELECTParser(tokens); + parser.setBuildParseTree(true); + ParseTree tree = parser.selectStmnt(); + + ParseTreeWalker walker = new ParseTreeWalker(); + walker.walk(this, tree); + + } + public void exitDerivedColumn(@NotNull SELECTParser.DerivedColumnContext ctx) { + selectObject.addColumnName(ctx.columnName().getText()); + } + + public void enterTablePrimary(@NotNull SELECTParser.TablePrimaryContext ctx) { + selectObject.addTableName(ctx.tableName().getText()); + } + + public SelectObject getSelectObject(){ + return this.selectObject; + } + + +} From deb431fac5d1e07fe38bf23d2a3876243ecc3bda Mon Sep 17 00:00:00 2001 From: Michele Castellana Date: Sun, 1 Dec 2013 22:53:21 +0100 Subject: [PATCH 02/37] Code maintenance: removed unused variables, fixed indentation, fixed imports, add comments etc. etc. --- src/com/etk/network/client/Client.java | 43 ++--- src/com/etk/network/server/JDBCServer.java | 14 +- .../etk/network/server/SessionHandler.java | 173 +++++++++--------- 3 files changed, 116 insertions(+), 114 deletions(-) diff --git a/src/com/etk/network/client/Client.java b/src/com/etk/network/client/Client.java index 83cab9e..f92ec29 100644 --- a/src/com/etk/network/client/Client.java +++ b/src/com/etk/network/client/Client.java @@ -1,7 +1,6 @@ package com.etk.network.client; import java.sql.Connection; -import java.sql.Date; import java.sql.DriverManager; import java.sql.ResultSet; import java.sql.SQLException; @@ -21,11 +20,11 @@ public Client() { // connect to the database conn = connectToDatabaseOrDie(); - System.out.println("Connected!"); - - // get data + System.out.println("Connected!"); + + // get data query(conn, list); - + System.out.println("QuerySent!"); // print results printAll(list); @@ -42,36 +41,34 @@ private void query(Connection conn, ArrayList list) { try { Statement st = conn.createStatement(); // the syntax for FROM is schema.table - ResultSet rs = st - .executeQuery("SELECT id FROM student.student"); + ResultSet rs = st.executeQuery("SELECT id FROM student.student"); while (rs.next()) { String name = rs.getString("name"); - System.out.println(name); - String surname = rs.getString("surname"); - System.out.println(surname); - // Date date = rs.getDate("date"); - //System.out.println(date.toString()); - - - } + System.out.println(name); + String surname = rs.getString("surname"); + System.out.println(surname); + // Date date = rs.getDate("date"); + // System.out.println(date.toString()); + + } rs.close(); st.close(); } catch (SQLException se) { System.err.println("Threw a SQLException."); - System.err.println(se.getMessage()); - se.printStackTrace(); - } + System.err.println(se.getMessage()); + se.printStackTrace(); + } } private Connection connectToDatabaseOrDie() { Connection conn = null; try { Class.forName("org.postgresql.Driver"); - String host = "127.0.0.1"; - String database = "Test"; - String username = "postgres"; - String password = "postgres"; - String url = "jdbc:postgresql://localhost:5000/dbname"; + String host = "localhost"; + String databaseName = "dbname"; + String username = "postgres"; + String password = "postgres"; + String url = "jdbc:postgresql://" + host + ":5000/" + databaseName; conn = DriverManager.getConnection(url, username, password); } catch (ClassNotFoundException e) { System.err.println("I have not found the PostgreSQL driver class"); diff --git a/src/com/etk/network/server/JDBCServer.java b/src/com/etk/network/server/JDBCServer.java index e4fb5ac..6f4de5a 100644 --- a/src/com/etk/network/server/JDBCServer.java +++ b/src/com/etk/network/server/JDBCServer.java @@ -1,28 +1,28 @@ package com.etk.network.server; -import java.io.*; -import java.net.*; +import java.io.IOException; +import java.net.ServerSocket; +import java.net.Socket; public class JDBCServer { - private static int port=5000, maxConnections=0; + private static int port=5000; + //TODO implement max number of connections? + // Listen for incoming connections and handle them public static void main(String[] args) { - int i=0; - try{ ServerSocket listener = new ServerSocket(port); Socket server; System.out.println("server started!"); while(true){ - SessionHandler connection; - server = listener.accept(); System.out.println("connection accepted"); SessionHandler conn_c= new SessionHandler(server); Thread t = new Thread(conn_c); t.start(); } + } catch (IOException ioe) { System.out.println("IOException on socket listen: " + ioe); ioe.printStackTrace(); diff --git a/src/com/etk/network/server/SessionHandler.java b/src/com/etk/network/server/SessionHandler.java index 7d6997b..6671f96 100644 --- a/src/com/etk/network/server/SessionHandler.java +++ b/src/com/etk/network/server/SessionHandler.java @@ -9,8 +9,6 @@ import java.util.Arrays; import java.util.LinkedList; -import com.etk.parser.SELECTMain; - class SessionHandler implements Runnable { private Socket server_; private String line_, input_; @@ -91,40 +89,53 @@ private void sendEmptyQueryResponseMessage(DataOutputStream dataOutputStream) dataOutputStream.writeInt(4); } - private void sendRowDescription(DataOutputStream dataOutputStream, String[] columns) throws IOException{ - + private void sendRowDescription(DataOutputStream dataOutputStream, + String[] columns) throws IOException { short fieldsNo = (short) columns.length; LinkedList bNameList = new LinkedList(); + // If the field can be identified as a column of a specific table, the + // object ID of the table; otherwise zero. int identificator = 0; + // If the field can be identified as a column of a specific table, the + // attribute number of the column; otherwise zero. short identificatorAtr = 0; + // The object ID of the field's data type. int typeInd = 0; + // The data type size (see pg_type.typlen). Note that negative values + // denote variable-width types. short typeLen = -2; + // The type modifier (see pg_attribute.atttypmod). The meaning of the + // modifier is type-specific. int typeMod = -1; + // The format code being used for the field. Currently will be zero + // (text) or one (binary). In a RowDescription returned from the + // statement variant of Describe, the format code is not yet known and + // will always be zero. short formatCode = 0; - - for (int i = 0; i < columns.length; i++){ - + + // Null terminate all column names + for (int i = 0; i < columns.length; i++) { String name = columns[i]; byte[] bName = nullTerminateString(name); bNameList.add(bName); } - + + // FIXME: Why 8 and not 6? int totalSize = 8; - - for(int i = 0; i < columns.length; i++){ - - totalSize = totalSize + bNameList.get(i).length; + + // calculate lenght of the of the message + for (int i = 0; i < columns.length; i++) { + totalSize += bNameList.get(i).length; } - - totalSize = totalSize + 14*columns.length; - - + + // FIXME: Why 14 and not 18? + totalSize = totalSize + 14 * columns.length; + dataOutputStream.writeByte('T'); dataOutputStream.writeInt(totalSize); dataOutputStream.writeShort(fieldsNo); - - for(int i = 0; i < columns.length; i++){ - + + for (int i = 0; i < columns.length; i++) { dataOutputStream.writeBytes(new String(bNameList.get(i))); dataOutputStream.writeInt(identificator); dataOutputStream.writeShort(identificatorAtr); @@ -132,49 +143,44 @@ private void sendRowDescription(DataOutputStream dataOutputStream, String[] colu dataOutputStream.writeShort(typeLen); dataOutputStream.writeInt(typeMod); dataOutputStream.writeShort(formatCode); - } - } - - private void sendDataRow(DataOutputStream dataOutputStream, String[] values) throws IOException{ - - - int tLen = 0; + + private void sendDataRow(DataOutputStream dataOutputStream, String[] values) + throws IOException { + // 4 bytes to communicate the lenght of the message + 2 bytes for the + // column numbers = 6 + int tLen = 6; short num = (short) values.length; LinkedList lenColList = new LinkedList(); LinkedList bvalList = new LinkedList(); - - - for(int i = 0; i < values.length; i ++){ - - String val = values[i]; - lenColList.add(nullTerminateString(val).length); - bvalList.add(nullTerminateString(val)); - tLen = tLen + nullTerminateString(val).length; + byte[] val; + + // Sum the length of the column value + for (int i = 0; i < values.length; i++) { + val = nullTerminateString(values[i]); + lenColList.add(val.length); + bvalList.add(val); + // lenght of the value + 4 bytes to communicate the value lenght + tLen += val.length + 4; } - - tLen = tLen + 6 + 4*values.length; - + dataOutputStream.writeByte('D'); dataOutputStream.writeInt(tLen); dataOutputStream.writeShort(num); - - for(int i = 0; i < values.length; i ++){ - + + // for each value, send 4 bytes for the value lenght and n bytes for + // the value itself + for (int i = 0; i < values.length; i++) { dataOutputStream.writeInt(lenColList.get(i)); - dataOutputStream.writeBytes(new String(nullTerminateString(values[i]))); + dataOutputStream.writeBytes(new String( + nullTerminateString(values[i]))); } - - - + } - - /* Data row incorrect, needs to be finished */ - public void run() { input_ = ""; @@ -241,9 +247,9 @@ public void run() { * dataOutputStream.flush(); */ - String[] columns = {"name", "surname"}; + String[] columns = { "name", "surname" }; sendRowDescription(dataOutputStream, columns); - String[] values = {"david", "riobo"}; + String[] values = { "david", "riobo" }; sendDataRow(dataOutputStream, values); dataOutputStream.flush(); @@ -258,7 +264,6 @@ public void run() { System.out.println("IOException on socket listen: " + ioe); ioe.printStackTrace(); } catch (Exception e) { - // TODO Auto-generated catch block e.printStackTrace(); } } @@ -378,52 +383,52 @@ private void sendData(DataOutputStream dataOutputStream) throws IOException { * Byten The value of the column, in the format indicated by the * associated format code. n is the above lengt */ - - for ( int i = 0; i < 2; i++){ - int tLen = 0; - short num = 4; + for (int i = 0; i < 2; i++) { - String val = "david"; - int lenCol = nullTerminateString(val).length; - byte[] bval = nullTerminateString(val); + int tLen = 0; + short num = 4; - String val2 = "riobo"; - int lenCol2 = nullTerminateString(val2).length; - byte[] bval2 = nullTerminateString(val2); + String val = "david"; + int lenCol = nullTerminateString(val).length; + byte[] bval = nullTerminateString(val); - String val3 = "1992-01-17"; - int lenCol3 = nullTerminateString(val3).length; - byte[] bval3 = nullTerminateString(val3); + String val2 = "riobo"; + int lenCol2 = nullTerminateString(val2).length; + byte[] bval2 = nullTerminateString(val2); - String val4 = "-87,61"; - int lenCol4 = nullTerminateString(val4).length; - byte[] bval4 = nullTerminateString(val4); + String val3 = "1992-01-17"; + int lenCol3 = nullTerminateString(val3).length; + byte[] bval3 = nullTerminateString(val3); - tLen = 4 + 2 + 4 + bval.length + 4 + bval2.length + 4 + bval3.length - + 4 + bval4.length; - dataOutputStream.writeByte('D'); - dataOutputStream.writeInt(tLen); - dataOutputStream.writeShort(num); + String val4 = "-87,61"; + int lenCol4 = nullTerminateString(val4).length; + byte[] bval4 = nullTerminateString(val4); + + tLen = 4 + 2 + 4 + bval.length + 4 + bval2.length + 4 + + bval3.length + 4 + bval4.length; + dataOutputStream.writeByte('D'); + dataOutputStream.writeInt(tLen); + dataOutputStream.writeShort(num); + + dataOutputStream.writeInt(lenCol); + dataOutputStream.writeBytes(new String(nullTerminateString(val))); - dataOutputStream.writeInt(lenCol); - dataOutputStream.writeBytes(new String(nullTerminateString(val))); + dataOutputStream.writeInt(lenCol2); + dataOutputStream.writeBytes(new String(nullTerminateString(val2))); - dataOutputStream.writeInt(lenCol2); - dataOutputStream.writeBytes(new String(nullTerminateString(val2))); + // Returns Bad value for type date : 1992-01-17 - // Returns Bad value for type date : 1992-01-17 + dataOutputStream.writeInt(lenCol3); + dataOutputStream.writeBytes(new String(nullTerminateString(val3))); - dataOutputStream.writeInt(lenCol3); - dataOutputStream.writeBytes(new String(nullTerminateString(val3))); + // Returns Bad value for type date too + + dataOutputStream.writeInt(lenCol4); + dataOutputStream.writeBytes(new String(nullTerminateString(val4))); - // Returns Bad value for type date too - - dataOutputStream.writeInt(lenCol4); - dataOutputStream.writeBytes(new String(nullTerminateString(val4))); - } - + dataOutputStream.flush(); } From 161b333fae96a3dbf20090e5a235ef8194474174 Mon Sep 17 00:00:00 2001 From: Michele Castellana Date: Tue, 3 Dec 2013 22:55:12 +0100 Subject: [PATCH 03/37] Added an helper class to send message and to encapsulate the "NullterminateString" function. Added some Javadocs. --- src/com/etk/network/server/Sender.java | 391 ++++++++++++++++++ .../etk/network/server/SessionHandler.java | 372 +---------------- 2 files changed, 408 insertions(+), 355 deletions(-) create mode 100644 src/com/etk/network/server/Sender.java diff --git a/src/com/etk/network/server/Sender.java b/src/com/etk/network/server/Sender.java new file mode 100644 index 0000000..233b81a --- /dev/null +++ b/src/com/etk/network/server/Sender.java @@ -0,0 +1,391 @@ +package com.etk.network.server; + +import java.io.DataOutputStream; +import java.io.IOException; +import java.util.LinkedList; + +public class Sender { + + private DataOutputStream dataOutputStream_; + + public Sender(DataOutputStream output) { + this.dataOutputStream_ = output; + } + + /** + * + * @throws IOException + */ + private void sendParseCompleteMessage() throws IOException { + this.dataOutputStream_.writeByte('1'); + this.dataOutputStream_.writeInt(4); + } + + /** + * + * @param dataOutputStream_ + * @throws IOException + */ + private void sendData() throws IOException { + /* + * RowDescription (B) Byte1('T') Identifies the message as a row + * description. Int32 Length of message contents in bytes, including + * self. Int16 Specifies the number of fields in a row (may be zero). + * Then, for each field, there is the following: String The field name. + * Int32 If the field can be identified as a column of a specific table, + * the object ID of the table; otherwise zero. Int16 If the field can be + * identified as a column of a specific table, the attribute number of + * the column; otherwise zero. Int32 The object ID of the field's data + * type. Int16 The data type size (see pg_type.typlen). Note that + * negative values denote variable-width types. Int32 The type modifier + * (see pg_attribute.atttypmod). The meaning of the modifier is + * type-specific. Int16 The format code being used for the field. + * Currently will be zero (text) or one (binary). In a RowDescription + * returned from the statement variant of Describe, the format code is + * not yet known and will always be zero. + * + * SSLRequest (F) + */ + + short fieldsNo = 4; + + String name = "name"; + byte[] bName = nullTerminateString(name); + int identificator = 0; + short identificatorAtr = 0; + int typeInd = 0; + short typeLen = -2; + int typeMod = -1; + short formatCode = 0; + + String name2 = "surname"; + byte[] bName2 = nullTerminateString(name2); + int identificator2 = 0; + short identificatorAtr2 = 0; + int typeInd2 = 0; + short typeLen2 = -2; + int typeMod2 = -1; + short formatCode2 = 0; + + String name3 = "date"; + byte[] bName3 = nullTerminateString(name3); + int identificator3 = 0; + short identificatorAtr3 = 0; + int typeInd3 = 0; + short typeLen3 = -2; + int typeMod3 = -1; + short formatCode3 = 0; + + String name4 = "number"; + byte[] bName4 = nullTerminateString(name4); + int identificator4 = 0; + short identificatorAtr4 = 0; + int typeInd4 = 0; + short typeLen4 = -2; + int typeMod4 = -1; + short formatCode4 = 0; + + int totalSize = bName.length + 4 + 2 + 4 + 2 + 4 + 2 + 4 + + bName3.length + 4 + 2 + 4 + 2 + 2 + bName4.length + 4 + 2 + 4 + + 2 + 2; + + this.dataOutputStream_.writeByte('T'); + this.dataOutputStream_.writeInt(totalSize); + this.dataOutputStream_.writeShort(fieldsNo); + + this.dataOutputStream_.writeBytes(new String(bName)); + this.dataOutputStream_.writeInt(identificator); + this.dataOutputStream_.writeShort(identificatorAtr); + this.dataOutputStream_.writeInt(typeInd); + this.dataOutputStream_.writeShort(typeLen); + this.dataOutputStream_.writeInt(typeMod); + this.dataOutputStream_.writeShort(formatCode); + + this.dataOutputStream_.writeBytes(new String(bName2)); + this.dataOutputStream_.writeInt(identificator2); + this.dataOutputStream_.writeShort(identificatorAtr2); + this.dataOutputStream_.writeInt(typeInd2); + this.dataOutputStream_.writeShort(typeLen2); + this.dataOutputStream_.writeInt(typeMod2); + this.dataOutputStream_.writeShort(formatCode2); + + this.dataOutputStream_.writeBytes(new String(bName3)); + this.dataOutputStream_.writeInt(identificator3); + this.dataOutputStream_.writeShort(identificatorAtr3); + this.dataOutputStream_.writeInt(typeInd3); + this.dataOutputStream_.writeShort(typeLen3); + this.dataOutputStream_.writeInt(typeMod3); + this.dataOutputStream_.writeShort(formatCode3); + + this.dataOutputStream_.writeBytes(new String(bName4)); + this.dataOutputStream_.writeInt(identificator4); + this.dataOutputStream_.writeShort(identificatorAtr4); + this.dataOutputStream_.writeInt(typeInd4); + this.dataOutputStream_.writeShort(typeLen4); + this.dataOutputStream_.writeInt(typeMod4); + this.dataOutputStream_.writeShort(formatCode4); + + /* + * Byte1('D') Identifies the message as a data row. + * + * Int32 Length of message contents in bytes, including self. + * + * Int16 The number of column values that follow (possibly zero). + * + * Next, the following pair of fields appear for each column: + * + * Int32 The length of the column value, in bytes (this count does not + * include itself). Can be zero. As a special case, -1 indicates a NULL + * column value. No value bytes follow in the NULL case. + * + * Byten The value of the column, in the format indicated by the + * associated format code. n is the above lengt + */ + + for (int i = 0; i < 2; i++) { + + int tLen = 0; + short num = 4; + + String val = "david"; + int lenCol = nullTerminateString(val).length; + byte[] bval = nullTerminateString(val); + + String val2 = "riobo"; + int lenCol2 = nullTerminateString(val2).length; + byte[] bval2 = nullTerminateString(val2); + + String val3 = "1992-01-17"; + int lenCol3 = nullTerminateString(val3).length; + byte[] bval3 = nullTerminateString(val3); + + String val4 = "-87,61"; + int lenCol4 = nullTerminateString(val4).length; + byte[] bval4 = nullTerminateString(val4); + + tLen = 4 + 2 + 4 + bval.length + 4 + bval2.length + 4 + + bval3.length + 4 + bval4.length; + this.dataOutputStream_.writeByte('D'); + this.dataOutputStream_.writeInt(tLen); + this.dataOutputStream_.writeShort(num); + + this.dataOutputStream_.writeInt(lenCol); + this.dataOutputStream_.writeBytes(new String( + nullTerminateString(val))); + + this.dataOutputStream_.writeInt(lenCol2); + this.dataOutputStream_.writeBytes(new String( + nullTerminateString(val2))); + + // Returns Bad value for type date : 1992-01-17 + + this.dataOutputStream_.writeInt(lenCol3); + this.dataOutputStream_.writeBytes(new String( + nullTerminateString(val3))); + + // Returns Bad value for type date too + + this.dataOutputStream_.writeInt(lenCol4); + this.dataOutputStream_.writeBytes(new String( + nullTerminateString(val4))); + + } + } + + /** + * + * @param string + * @return + */ + private byte[] nullTerminateString(String string) { + byte[] in = string.getBytes(); + byte[] out = new byte[in.length + 1]; + for (int i = 0; i < in.length; i++) { + out[i] = in[i]; + } + out[in.length] = 0; + return out; + } + + /** + * + * @throws IOException + */ + public void sendServerVersionMessage() throws IOException { + String param = "server_version"; + String paramV = "9"; + + byte[] nameB = nullTerminateString(param); // PEACE OF SHIT NEEDS TO BE + // NULTERMINATED EVEN THOUGH DOCS + // DONT MENTION IT + byte[] valB = nullTerminateString(paramV); + + this.dataOutputStream_.writeByte('S'); + this.dataOutputStream_.writeInt(4 + nameB.length + valB.length); + this.dataOutputStream_.write(nameB); + this.dataOutputStream_.write(valB); + } + + /** + * + * @throws IOException + */ + public void sendReadyForQueryMessage() throws IOException { + this.dataOutputStream_.writeByte('Z'); + this.dataOutputStream_.writeInt(5); + this.dataOutputStream_.writeByte('I'); + } + + /** + * + * @param columns + * @throws IOException + */ + public void sendRowDescription(String[] columns) throws IOException { + short fieldsNo = (short) columns.length; + LinkedList bNameList = new LinkedList(); + // If the field can be identified as a column of a specific table, the + // object ID of the table; otherwise zero. + int identificator = 0; + // If the field can be identified as a column of a specific table, the + // attribute number of the column; otherwise zero. + short identificatorAtr = 0; + // The object ID of the field's data type. + int typeInd = 0; + // The data type size (see pg_type.typlen). Note that negative values + // denote variable-width types. + short typeLen = -2; + // The type modifier (see pg_attribute.atttypmod). The meaning of the + // modifier is type-specific. + int typeMod = -1; + // The format code being used for the field. Currently will be zero + // (text) or one (binary). In a RowDescription returned from the + // statement variant of Describe, the format code is not yet known and + // will always be zero. + short formatCode = 0; + + // Null terminate all column names + for (int i = 0; i < columns.length; i++) { + String name = columns[i]; + byte[] bName = nullTerminateString(name); + bNameList.add(bName); + } + + // FIXME: Why 8 and not 6? + int totalSize = 8; + + // calculate lenght of the of the message + for (int i = 0; i < columns.length; i++) { + totalSize += bNameList.get(i).length; + } + + // FIXME: Why 14 and not 18? + totalSize = totalSize + 14 * columns.length; + + this.dataOutputStream_.writeByte('T'); + this.dataOutputStream_.writeInt(totalSize); + this.dataOutputStream_.writeShort(fieldsNo); + + for (int i = 0; i < columns.length; i++) { + this.dataOutputStream_.writeBytes(new String(bNameList.get(i))); + this.dataOutputStream_.writeInt(identificator); + this.dataOutputStream_.writeShort(identificatorAtr); + this.dataOutputStream_.writeInt(typeInd); + this.dataOutputStream_.writeShort(typeLen); + this.dataOutputStream_.writeInt(typeMod); + this.dataOutputStream_.writeShort(formatCode); + } + } + + /** + * + * @throws IOException + */ + public void sendCommandCompleteMessage() throws IOException { + this.dataOutputStream_.writeByte('C'); + String tmp = "SELECT 1"; + this.dataOutputStream_.writeInt(4 + tmp.getBytes().length); + this.dataOutputStream_.write(tmp.getBytes()); + } + + /** + * + * @param values + * @throws IOException + */ + public void sendDataRow(String[] values) throws IOException { + // 4 bytes to communicate the lenght of the message + 2 bytes for the + // column numbers = 6 + int tLen = 6; + short num = (short) values.length; + LinkedList lenColList = new LinkedList(); + LinkedList bvalList = new LinkedList(); + byte[] val; + + // Sum the length of the column value + for (int i = 0; i < values.length; i++) { + val = nullTerminateString(values[i]); + lenColList.add(val.length); + bvalList.add(val); + // lenght of the value + 4 bytes to communicate the value lenght + tLen += val.length + 4; + } + + this.dataOutputStream_.writeByte('D'); + this.dataOutputStream_.writeInt(tLen); + this.dataOutputStream_.writeShort(num); + + // for each value, send 4 bytes for the value lenght and n bytes for + // the value itself + for (int i = 0; i < values.length; i++) { + this.dataOutputStream_.writeInt(lenColList.get(i)); + this.dataOutputStream_.writeBytes(new String( + nullTerminateString(values[i]))); + } + } + + /** + * + * @throws IOException + */ + public void flush() throws IOException { + this.dataOutputStream_.flush(); + } + + /** + * + * @throws IOException + */ + public void sendAuthenticationOkMessage() throws IOException { + this.dataOutputStream_.writeByte('R'); + this.dataOutputStream_.writeInt(8); + this.dataOutputStream_.writeInt(0); + } + + /** + * + * @throws IOException + */ + private void sendBindCompleteMessage() throws IOException { + this.dataOutputStream_.writeByte('2'); + this.dataOutputStream_.writeInt(4); + } + + /** + * + * @throws IOException + */ + private void sendEmptyQueryResponseMessage() throws IOException { + this.dataOutputStream_.writeByte('I'); + this.dataOutputStream_.writeInt(4); + } + + /** + * + * @throws IOException + */ + private void sendTerminateMessage() throws IOException { + this.dataOutputStream_.writeByte('X'); + this.dataOutputStream_.writeInt(4); + } +} diff --git a/src/com/etk/network/server/SessionHandler.java b/src/com/etk/network/server/SessionHandler.java index 6671f96..9570587 100644 --- a/src/com/etk/network/server/SessionHandler.java +++ b/src/com/etk/network/server/SessionHandler.java @@ -7,189 +7,28 @@ import java.net.Socket; import java.nio.ByteBuffer; import java.util.Arrays; -import java.util.LinkedList; class SessionHandler implements Runnable { private Socket server_; - private String line_, input_; + private Sender sender_; - SessionHandler(Socket server) { + public SessionHandler(Socket server) { this.server_ = server; - } - - private byte[] nullTerminateString(String string) { - byte[] in = string.getBytes(); - byte[] out = new byte[in.length + 1]; - for (int i = 0; i < in.length; i++) { - out[i] = in[i]; - } - out[in.length] = 0; - return out; - } - - private void sendServerVersionMessage(DataOutputStream dataOutputStream) - throws IOException { - String param = "server_version"; - String paramV = "9"; - - byte[] nameB = nullTerminateString(param); // PEACE OF SHIT NEEDS TO BE - // NULTERMINATED EVEN THOUGH DOCS - // DONT MENTION IT - byte[] valB = nullTerminateString(paramV); - - dataOutputStream.writeByte('S'); - dataOutputStream.writeInt(4 + nameB.length + valB.length); - dataOutputStream.write(nameB); - dataOutputStream.write(valB); - } - - private void sendAuthenticationOkMessage(DataOutputStream dataOutputStream) - throws IOException { - dataOutputStream.writeByte('R'); - dataOutputStream.writeInt(8); - dataOutputStream.writeInt(0); - } - - private void sendReadyForQueryMessage(DataOutputStream dataOutputStream) - throws IOException { - dataOutputStream.writeByte('Z'); - dataOutputStream.writeInt(5); - dataOutputStream.writeByte('I'); - } - - private void sendTerminateMessage(DataOutputStream dataOutputStream) - throws IOException { - dataOutputStream.writeByte('X'); - dataOutputStream.writeInt(4); - } - - private void sendCommandCompleteMessage(DataOutputStream dataOutputStream) - throws IOException { - dataOutputStream.writeByte('C'); - String tmp = "SELECT 1"; - dataOutputStream.writeInt(4 + tmp.getBytes().length); - dataOutputStream.write(tmp.getBytes()); - } - - private void sendParseCompleteMessage(DataOutputStream dataOutputStream) - throws IOException { - dataOutputStream.writeByte('1'); - dataOutputStream.writeInt(4); - } - - private void sendBindCompleteMessage(DataOutputStream dataOutputStream) - throws IOException { - dataOutputStream.writeByte('2'); - dataOutputStream.writeInt(4); - } - - private void sendEmptyQueryResponseMessage(DataOutputStream dataOutputStream) - throws IOException { - dataOutputStream.writeByte('I'); - dataOutputStream.writeInt(4); - } - - private void sendRowDescription(DataOutputStream dataOutputStream, - String[] columns) throws IOException { - short fieldsNo = (short) columns.length; - LinkedList bNameList = new LinkedList(); - // If the field can be identified as a column of a specific table, the - // object ID of the table; otherwise zero. - int identificator = 0; - // If the field can be identified as a column of a specific table, the - // attribute number of the column; otherwise zero. - short identificatorAtr = 0; - // The object ID of the field's data type. - int typeInd = 0; - // The data type size (see pg_type.typlen). Note that negative values - // denote variable-width types. - short typeLen = -2; - // The type modifier (see pg_attribute.atttypmod). The meaning of the - // modifier is type-specific. - int typeMod = -1; - // The format code being used for the field. Currently will be zero - // (text) or one (binary). In a RowDescription returned from the - // statement variant of Describe, the format code is not yet known and - // will always be zero. - short formatCode = 0; - - // Null terminate all column names - for (int i = 0; i < columns.length; i++) { - String name = columns[i]; - byte[] bName = nullTerminateString(name); - bNameList.add(bName); - } - - // FIXME: Why 8 and not 6? - int totalSize = 8; - - // calculate lenght of the of the message - for (int i = 0; i < columns.length; i++) { - totalSize += bNameList.get(i).length; - } - - // FIXME: Why 14 and not 18? - totalSize = totalSize + 14 * columns.length; - - dataOutputStream.writeByte('T'); - dataOutputStream.writeInt(totalSize); - dataOutputStream.writeShort(fieldsNo); - - for (int i = 0; i < columns.length; i++) { - dataOutputStream.writeBytes(new String(bNameList.get(i))); - dataOutputStream.writeInt(identificator); - dataOutputStream.writeShort(identificatorAtr); - dataOutputStream.writeInt(typeInd); - dataOutputStream.writeShort(typeLen); - dataOutputStream.writeInt(typeMod); - dataOutputStream.writeShort(formatCode); - } - } - - private void sendDataRow(DataOutputStream dataOutputStream, String[] values) - throws IOException { - // 4 bytes to communicate the lenght of the message + 2 bytes for the - // column numbers = 6 - int tLen = 6; - short num = (short) values.length; - LinkedList lenColList = new LinkedList(); - LinkedList bvalList = new LinkedList(); - byte[] val; - - // Sum the length of the column value - for (int i = 0; i < values.length; i++) { - val = nullTerminateString(values[i]); - lenColList.add(val.length); - bvalList.add(val); - // lenght of the value + 4 bytes to communicate the value lenght - tLen += val.length + 4; - } - - dataOutputStream.writeByte('D'); - dataOutputStream.writeInt(tLen); - dataOutputStream.writeShort(num); - - // for each value, send 4 bytes for the value lenght and n bytes for - // the value itself - for (int i = 0; i < values.length; i++) { - dataOutputStream.writeInt(lenColList.get(i)); - dataOutputStream.writeBytes(new String( - nullTerminateString(values[i]))); + try { + this.sender_ = new Sender(new DataOutputStream( + server_.getOutputStream())); + } catch (IOException e) { + e.printStackTrace(); } - } /* Data row incorrect, needs to be finished */ public void run() { - input_ = ""; - try { DataInputStream dataInputStream = new DataInputStream( server_.getInputStream()); - DataOutputStream dataOutputStream = new DataOutputStream( - server_.getOutputStream()); MsgParser msgParser = new MsgParser(); @@ -209,22 +48,10 @@ public void run() { // System.out.println("Auth params: " + authParams); - sendAuthenticationOkMessage(dataOutputStream); - - /* - * os.writeByte('K'); os.writeInt(12); os.writeInt(2); - * os.writeInt(3); - */ - - this.sendServerVersionMessage(dataOutputStream); - - this.sendReadyForQueryMessage(dataOutputStream); - - dataOutputStream.flush(); - - /* - * I think now the client wants the result of the query - */ + this.sender_.sendAuthenticationOkMessage(); + this.sender_.sendServerVersionMessage(); + this.sender_.sendReadyForQueryMessage(); + this.sender_.flush(); // if (dataInputStream.available() > 0) { byte type = dataInputStream.readByte(); @@ -248,14 +75,14 @@ public void run() { */ String[] columns = { "name", "surname" }; - sendRowDescription(dataOutputStream, columns); + this.sender_.sendRowDescription(columns); String[] values = { "david", "riobo" }; - sendDataRow(dataOutputStream, values); - dataOutputStream.flush(); + this.sender_.sendDataRow(values); + this.sender_.flush(); - sendCommandCompleteMessage(dataOutputStream); - sendReadyForQueryMessage(dataOutputStream); - dataOutputStream.flush(); + this.sender_.sendCommandCompleteMessage(); + this.sender_.sendReadyForQueryMessage(); + this.sender_.flush(); // reply to the client msg, delete exit // } @@ -268,171 +95,6 @@ public void run() { } } - private void sendData(DataOutputStream dataOutputStream) throws IOException { - /* - * RowDescription (B) Byte1('T') Identifies the message as a row - * description. Int32 Length of message contents in bytes, including - * self. Int16 Specifies the number of fields in a row (may be zero). - * Then, for each field, there is the following: String The field name. - * Int32 If the field can be identified as a column of a specific table, - * the object ID of the table; otherwise zero. Int16 If the field can be - * identified as a column of a specific table, the attribute number of - * the column; otherwise zero. Int32 The object ID of the field's data - * type. Int16 The data type size (see pg_type.typlen). Note that - * negative values denote variable-width types. Int32 The type modifier - * (see pg_attribute.atttypmod). The meaning of the modifier is - * type-specific. Int16 The format code being used for the field. - * Currently will be zero (text) or one (binary). In a RowDescription - * returned from the statement variant of Describe, the format code is - * not yet known and will always be zero. - * - * SSLRequest (F) - */ - - short fieldsNo = 4; - - String name = "name"; - byte[] bName = nullTerminateString(name); - int identificator = 0; - short identificatorAtr = 0; - int typeInd = 0; - short typeLen = -2; - int typeMod = -1; - short formatCode = 0; - - String name2 = "surname"; - byte[] bName2 = nullTerminateString(name2); - int identificator2 = 0; - short identificatorAtr2 = 0; - int typeInd2 = 0; - short typeLen2 = -2; - int typeMod2 = -1; - short formatCode2 = 0; - - String name3 = "date"; - byte[] bName3 = nullTerminateString(name3); - int identificator3 = 0; - short identificatorAtr3 = 0; - int typeInd3 = 0; - short typeLen3 = -2; - int typeMod3 = -1; - short formatCode3 = 0; - - String name4 = "number"; - byte[] bName4 = nullTerminateString(name4); - int identificator4 = 0; - short identificatorAtr4 = 0; - int typeInd4 = 0; - short typeLen4 = -2; - int typeMod4 = -1; - short formatCode4 = 0; - - int totalSize = bName.length + 4 + 2 + 4 + 2 + 4 + 2 + 4 - + bName3.length + 4 + 2 + 4 + 2 + 2 + bName4.length + 4 + 2 + 4 - + 2 + 2; - - dataOutputStream.writeByte('T'); - dataOutputStream.writeInt(totalSize); - dataOutputStream.writeShort(fieldsNo); - - dataOutputStream.writeBytes(new String(bName)); - dataOutputStream.writeInt(identificator); - dataOutputStream.writeShort(identificatorAtr); - dataOutputStream.writeInt(typeInd); - dataOutputStream.writeShort(typeLen); - dataOutputStream.writeInt(typeMod); - dataOutputStream.writeShort(formatCode); - - dataOutputStream.writeBytes(new String(bName2)); - dataOutputStream.writeInt(identificator2); - dataOutputStream.writeShort(identificatorAtr2); - dataOutputStream.writeInt(typeInd2); - dataOutputStream.writeShort(typeLen2); - dataOutputStream.writeInt(typeMod2); - dataOutputStream.writeShort(formatCode2); - - dataOutputStream.writeBytes(new String(bName3)); - dataOutputStream.writeInt(identificator3); - dataOutputStream.writeShort(identificatorAtr3); - dataOutputStream.writeInt(typeInd3); - dataOutputStream.writeShort(typeLen3); - dataOutputStream.writeInt(typeMod3); - dataOutputStream.writeShort(formatCode3); - - dataOutputStream.writeBytes(new String(bName4)); - dataOutputStream.writeInt(identificator4); - dataOutputStream.writeShort(identificatorAtr4); - dataOutputStream.writeInt(typeInd4); - dataOutputStream.writeShort(typeLen4); - dataOutputStream.writeInt(typeMod4); - dataOutputStream.writeShort(formatCode4); - - /* - * Byte1('D') Identifies the message as a data row. - * - * Int32 Length of message contents in bytes, including self. - * - * Int16 The number of column values that follow (possibly zero). - * - * Next, the following pair of fields appear for each column: - * - * Int32 The length of the column value, in bytes (this count does not - * include itself). Can be zero. As a special case, -1 indicates a NULL - * column value. No value bytes follow in the NULL case. - * - * Byten The value of the column, in the format indicated by the - * associated format code. n is the above lengt - */ - - for (int i = 0; i < 2; i++) { - - int tLen = 0; - short num = 4; - - String val = "david"; - int lenCol = nullTerminateString(val).length; - byte[] bval = nullTerminateString(val); - - String val2 = "riobo"; - int lenCol2 = nullTerminateString(val2).length; - byte[] bval2 = nullTerminateString(val2); - - String val3 = "1992-01-17"; - int lenCol3 = nullTerminateString(val3).length; - byte[] bval3 = nullTerminateString(val3); - - String val4 = "-87,61"; - int lenCol4 = nullTerminateString(val4).length; - byte[] bval4 = nullTerminateString(val4); - - tLen = 4 + 2 + 4 + bval.length + 4 + bval2.length + 4 - + bval3.length + 4 + bval4.length; - dataOutputStream.writeByte('D'); - dataOutputStream.writeInt(tLen); - dataOutputStream.writeShort(num); - - dataOutputStream.writeInt(lenCol); - dataOutputStream.writeBytes(new String(nullTerminateString(val))); - - dataOutputStream.writeInt(lenCol2); - dataOutputStream.writeBytes(new String(nullTerminateString(val2))); - - // Returns Bad value for type date : 1992-01-17 - - dataOutputStream.writeInt(lenCol3); - dataOutputStream.writeBytes(new String(nullTerminateString(val3))); - - // Returns Bad value for type date too - - dataOutputStream.writeInt(lenCol4); - dataOutputStream.writeBytes(new String(nullTerminateString(val4))); - - } - - dataOutputStream.flush(); - - } - private class MsgParser { public short parseShort(byte[] bytes) { From 20c436edd293972eefbe32e7b763c1750922316e Mon Sep 17 00:00:00 2001 From: supervitis Date: Wed, 4 Dec 2013 13:51:16 +0100 Subject: [PATCH 04/37] Updated client with simple menu --- src/com/etk/network/client/Client.java | 51 +++++++++++++++++++++++--- 1 file changed, 45 insertions(+), 6 deletions(-) diff --git a/src/com/etk/network/client/Client.java b/src/com/etk/network/client/Client.java index f92ec29..1e14238 100644 --- a/src/com/etk/network/client/Client.java +++ b/src/com/etk/network/client/Client.java @@ -1,5 +1,8 @@ package com.etk.network.client; +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; import java.sql.Connection; import java.sql.DriverManager; import java.sql.ResultSet; @@ -10,6 +13,9 @@ public class Client { + private InputStreamReader isr_ = new InputStreamReader(System.in); + private BufferedReader br_ = new BufferedReader(isr_); + public static void main(String[] args) { new Client(); } @@ -21,13 +27,46 @@ public Client() { // connect to the database conn = connectToDatabaseOrDie(); System.out.println("Connected!"); + boolean exit = false; + + while (!exit) { + System.out.println("Choose option:"); + System.out.println("1-Enter query"); + System.out.println("2-Quit"); + int option = 0; + try { + option = Integer.parseInt(br_.readLine()); + } catch (IOException e1) { + // TODO Auto-generated catch block + e1.printStackTrace(); + } + switch (option) { + case 1: - // get data - query(conn, list); + System.out.println("Write the query: "); + String query = null; + try { + query = br_.readLine(); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } - System.out.println("QuerySent!"); - // print results - printAll(list); + // get data + query(conn, list, query); + + System.out.println("QuerySent!"); + // print results + printAll(list); + break; + case 2: + exit = true; + break; + default: + System.out.println("Invalid option"); + break; + } + } } private void printAll(ArrayList list) { @@ -37,7 +76,7 @@ private void printAll(ArrayList list) { } } - private void query(Connection conn, ArrayList list) { + private void query(Connection conn, ArrayList list, String query) { try { Statement st = conn.createStatement(); // the syntax for FROM is schema.table From 59ee21cbdf2c6aab89a05bdd24a3fa4dde562382 Mon Sep 17 00:00:00 2001 From: supervitis Date: Wed, 4 Dec 2013 13:59:09 +0100 Subject: [PATCH 05/37] Parser added --- src/com/etk/network/server/SessionHandler.java | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/com/etk/network/server/SessionHandler.java b/src/com/etk/network/server/SessionHandler.java index 9570587..d2e5d67 100644 --- a/src/com/etk/network/server/SessionHandler.java +++ b/src/com/etk/network/server/SessionHandler.java @@ -1,13 +1,18 @@ package com.etk.network.server; +import java.io.ByteArrayInputStream; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.IOException; +import java.io.InputStream; import java.io.UnsupportedEncodingException; import java.net.Socket; import java.nio.ByteBuffer; import java.util.Arrays; +import com.etk.parser.SelectObject; +import com.etk.parser.SelectQueryToObject; + class SessionHandler implements Runnable { private Socket server_; private Sender sender_; @@ -63,9 +68,19 @@ public void run() { dataInputStream.read(buf); String inputString = msgParser.parseMsg(buf); System.out.println(inputString); + InputStream is = new ByteArrayInputStream( + inputString.getBytes("UTF-8")); + SelectQueryToObject transform = new SelectQueryToObject(is); + SelectObject selectObject = transform.getSelectObject(); + + System.out.println("Parser found tables: " + + selectObject.getTableNames().toString() + + "\nParser found columns: " + + selectObject.getColumnNames().toString()); // InputStream is = new // ByteArrayInputStream(inputString.getBytes("UTF-8")); // SELECTMain.parse(is); + /* * this is in case the server receive an empty query string and From 5976257bf8eef2d6e4d10aeba86b1e6a9ecb37bd Mon Sep 17 00:00:00 2001 From: supervitis Date: Wed, 4 Dec 2013 14:27:20 +0100 Subject: [PATCH 06/37] Parser connected, error on tokens. --- src/com/etk/parser/SelectQueryToObject.java | 28 ++++++++++----------- 1 file changed, 13 insertions(+), 15 deletions(-) diff --git a/src/com/etk/parser/SelectQueryToObject.java b/src/com/etk/parser/SelectQueryToObject.java index 9b96617..1a60d4d 100644 --- a/src/com/etk/parser/SelectQueryToObject.java +++ b/src/com/etk/parser/SelectQueryToObject.java @@ -20,23 +20,21 @@ public class SelectQueryToObject extends SELECTBaseListener { private SelectObject selectObject; - public SelectQueryToObject(String[] args) throws Exception { + public SelectQueryToObject(InputStream parseString) throws Exception { selectObject = new SelectObject(); - String inputFile = null; - if ( args.length>0 ) inputFile = args[0]; - InputStream is = System.in; - if ( inputFile!=null ) { - is = new FileInputStream(inputFile); + + + if ( parseString!= null ) { + ANTLRInputStream input = new ANTLRInputStream(parseString); + SELECTLexer lexer = new SELECTLexer(input); + CommonTokenStream tokens = new CommonTokenStream(lexer); + SELECTParser parser = new SELECTParser(tokens); + parser.setBuildParseTree(true); + ParseTree tree = parser.selectStmnt(); + + ParseTreeWalker walker = new ParseTreeWalker(); + walker.walk(this, tree); } - ANTLRInputStream input = new ANTLRInputStream(is); - SELECTLexer lexer = new SELECTLexer(input); - CommonTokenStream tokens = new CommonTokenStream(lexer); - SELECTParser parser = new SELECTParser(tokens); - parser.setBuildParseTree(true); - ParseTree tree = parser.selectStmnt(); - - ParseTreeWalker walker = new ParseTreeWalker(); - walker.walk(this, tree); } public void exitDerivedColumn(@NotNull SELECTParser.DerivedColumnContext ctx) { From e0292a722ef656691b28c8753b13b666e6a46d8e Mon Sep 17 00:00:00 2001 From: Michele Castellana Date: Wed, 4 Dec 2013 15:40:35 +0100 Subject: [PATCH 07/37] A better handling of exceptions --- src/com/etk/network/server/Sender.java | 605 ++++++++++++++----------- 1 file changed, 333 insertions(+), 272 deletions(-) diff --git a/src/com/etk/network/server/Sender.java b/src/com/etk/network/server/Sender.java index 233b81a..63646f6 100644 --- a/src/com/etk/network/server/Sender.java +++ b/src/com/etk/network/server/Sender.java @@ -14,19 +14,22 @@ public Sender(DataOutputStream output) { /** * - * @throws IOException */ - private void sendParseCompleteMessage() throws IOException { - this.dataOutputStream_.writeByte('1'); - this.dataOutputStream_.writeInt(4); + public void sendParseCompleteMessage() { + try { + this.dataOutputStream_.writeByte('1'); + this.dataOutputStream_.writeInt(4); + } catch (IOException e) { + System.out.println("Error in sendParseCompleteMessage: "); + e.printStackTrace(); + } + } /** * - * @param dataOutputStream_ - * @throws IOException */ - private void sendData() throws IOException { + private void sendData() { /* * RowDescription (B) Byte1('T') Identifies the message as a row * description. Int32 Length of message contents in bytes, including @@ -47,148 +50,153 @@ private void sendData() throws IOException { * SSLRequest (F) */ - short fieldsNo = 4; - - String name = "name"; - byte[] bName = nullTerminateString(name); - int identificator = 0; - short identificatorAtr = 0; - int typeInd = 0; - short typeLen = -2; - int typeMod = -1; - short formatCode = 0; - - String name2 = "surname"; - byte[] bName2 = nullTerminateString(name2); - int identificator2 = 0; - short identificatorAtr2 = 0; - int typeInd2 = 0; - short typeLen2 = -2; - int typeMod2 = -1; - short formatCode2 = 0; - - String name3 = "date"; - byte[] bName3 = nullTerminateString(name3); - int identificator3 = 0; - short identificatorAtr3 = 0; - int typeInd3 = 0; - short typeLen3 = -2; - int typeMod3 = -1; - short formatCode3 = 0; - - String name4 = "number"; - byte[] bName4 = nullTerminateString(name4); - int identificator4 = 0; - short identificatorAtr4 = 0; - int typeInd4 = 0; - short typeLen4 = -2; - int typeMod4 = -1; - short formatCode4 = 0; - - int totalSize = bName.length + 4 + 2 + 4 + 2 + 4 + 2 + 4 - + bName3.length + 4 + 2 + 4 + 2 + 2 + bName4.length + 4 + 2 + 4 - + 2 + 2; - - this.dataOutputStream_.writeByte('T'); - this.dataOutputStream_.writeInt(totalSize); - this.dataOutputStream_.writeShort(fieldsNo); - - this.dataOutputStream_.writeBytes(new String(bName)); - this.dataOutputStream_.writeInt(identificator); - this.dataOutputStream_.writeShort(identificatorAtr); - this.dataOutputStream_.writeInt(typeInd); - this.dataOutputStream_.writeShort(typeLen); - this.dataOutputStream_.writeInt(typeMod); - this.dataOutputStream_.writeShort(formatCode); - - this.dataOutputStream_.writeBytes(new String(bName2)); - this.dataOutputStream_.writeInt(identificator2); - this.dataOutputStream_.writeShort(identificatorAtr2); - this.dataOutputStream_.writeInt(typeInd2); - this.dataOutputStream_.writeShort(typeLen2); - this.dataOutputStream_.writeInt(typeMod2); - this.dataOutputStream_.writeShort(formatCode2); - - this.dataOutputStream_.writeBytes(new String(bName3)); - this.dataOutputStream_.writeInt(identificator3); - this.dataOutputStream_.writeShort(identificatorAtr3); - this.dataOutputStream_.writeInt(typeInd3); - this.dataOutputStream_.writeShort(typeLen3); - this.dataOutputStream_.writeInt(typeMod3); - this.dataOutputStream_.writeShort(formatCode3); - - this.dataOutputStream_.writeBytes(new String(bName4)); - this.dataOutputStream_.writeInt(identificator4); - this.dataOutputStream_.writeShort(identificatorAtr4); - this.dataOutputStream_.writeInt(typeInd4); - this.dataOutputStream_.writeShort(typeLen4); - this.dataOutputStream_.writeInt(typeMod4); - this.dataOutputStream_.writeShort(formatCode4); - - /* - * Byte1('D') Identifies the message as a data row. - * - * Int32 Length of message contents in bytes, including self. - * - * Int16 The number of column values that follow (possibly zero). - * - * Next, the following pair of fields appear for each column: - * - * Int32 The length of the column value, in bytes (this count does not - * include itself). Can be zero. As a special case, -1 indicates a NULL - * column value. No value bytes follow in the NULL case. - * - * Byten The value of the column, in the format indicated by the - * associated format code. n is the above lengt - */ - - for (int i = 0; i < 2; i++) { - - int tLen = 0; - short num = 4; - - String val = "david"; - int lenCol = nullTerminateString(val).length; - byte[] bval = nullTerminateString(val); - - String val2 = "riobo"; - int lenCol2 = nullTerminateString(val2).length; - byte[] bval2 = nullTerminateString(val2); - - String val3 = "1992-01-17"; - int lenCol3 = nullTerminateString(val3).length; - byte[] bval3 = nullTerminateString(val3); - - String val4 = "-87,61"; - int lenCol4 = nullTerminateString(val4).length; - byte[] bval4 = nullTerminateString(val4); + try { + short fieldsNo = 4; - tLen = 4 + 2 + 4 + bval.length + 4 + bval2.length + 4 - + bval3.length + 4 + bval4.length; - this.dataOutputStream_.writeByte('D'); - this.dataOutputStream_.writeInt(tLen); - this.dataOutputStream_.writeShort(num); - - this.dataOutputStream_.writeInt(lenCol); - this.dataOutputStream_.writeBytes(new String( - nullTerminateString(val))); - - this.dataOutputStream_.writeInt(lenCol2); - this.dataOutputStream_.writeBytes(new String( - nullTerminateString(val2))); - - // Returns Bad value for type date : 1992-01-17 - - this.dataOutputStream_.writeInt(lenCol3); - this.dataOutputStream_.writeBytes(new String( - nullTerminateString(val3))); - - // Returns Bad value for type date too - - this.dataOutputStream_.writeInt(lenCol4); - this.dataOutputStream_.writeBytes(new String( - nullTerminateString(val4))); + String name = "name"; + byte[] bName = nullTerminateString(name); + int identificator = 0; + short identificatorAtr = 0; + int typeInd = 0; + short typeLen = -2; + int typeMod = -1; + short formatCode = 0; + + String name2 = "surname"; + byte[] bName2 = nullTerminateString(name2); + int identificator2 = 0; + short identificatorAtr2 = 0; + int typeInd2 = 0; + short typeLen2 = -2; + int typeMod2 = -1; + short formatCode2 = 0; + + String name3 = "date"; + byte[] bName3 = nullTerminateString(name3); + int identificator3 = 0; + short identificatorAtr3 = 0; + int typeInd3 = 0; + short typeLen3 = -2; + int typeMod3 = -1; + short formatCode3 = 0; + + String name4 = "number"; + byte[] bName4 = nullTerminateString(name4); + int identificator4 = 0; + short identificatorAtr4 = 0; + int typeInd4 = 0; + short typeLen4 = -2; + int typeMod4 = -1; + short formatCode4 = 0; + + int totalSize = bName.length + 4 + 2 + 4 + 2 + 4 + 2 + 4 + + bName3.length + 4 + 2 + 4 + 2 + 2 + bName4.length + 4 + 2 + + 4 + 2 + 2; + + this.dataOutputStream_.writeByte('T'); + this.dataOutputStream_.writeInt(totalSize); + this.dataOutputStream_.writeShort(fieldsNo); + + this.dataOutputStream_.writeBytes(new String(bName)); + this.dataOutputStream_.writeInt(identificator); + this.dataOutputStream_.writeShort(identificatorAtr); + this.dataOutputStream_.writeInt(typeInd); + this.dataOutputStream_.writeShort(typeLen); + this.dataOutputStream_.writeInt(typeMod); + this.dataOutputStream_.writeShort(formatCode); + this.dataOutputStream_.writeBytes(new String(bName2)); + this.dataOutputStream_.writeInt(identificator2); + this.dataOutputStream_.writeShort(identificatorAtr2); + this.dataOutputStream_.writeInt(typeInd2); + this.dataOutputStream_.writeShort(typeLen2); + this.dataOutputStream_.writeInt(typeMod2); + this.dataOutputStream_.writeShort(formatCode2); + + this.dataOutputStream_.writeBytes(new String(bName3)); + this.dataOutputStream_.writeInt(identificator3); + this.dataOutputStream_.writeShort(identificatorAtr3); + this.dataOutputStream_.writeInt(typeInd3); + this.dataOutputStream_.writeShort(typeLen3); + this.dataOutputStream_.writeInt(typeMod3); + this.dataOutputStream_.writeShort(formatCode3); + + this.dataOutputStream_.writeBytes(new String(bName4)); + this.dataOutputStream_.writeInt(identificator4); + this.dataOutputStream_.writeShort(identificatorAtr4); + this.dataOutputStream_.writeInt(typeInd4); + this.dataOutputStream_.writeShort(typeLen4); + this.dataOutputStream_.writeInt(typeMod4); + this.dataOutputStream_.writeShort(formatCode4); + + /* + * Byte1('D') Identifies the message as a data row. + * + * Int32 Length of message contents in bytes, including self. + * + * Int16 The number of column values that follow (possibly zero). + * + * Next, the following pair of fields appear for each column: + * + * Int32 The length of the column value, in bytes (this count does + * not include itself). Can be zero. As a special case, -1 indicates + * a NULL column value. No value bytes follow in the NULL case. + * + * Byten The value of the column, in the format indicated by the + * associated format code. n is the above lengt + */ + + for (int i = 0; i < 2; i++) { + + int tLen = 0; + short num = 4; + + String val = "david"; + int lenCol = nullTerminateString(val).length; + byte[] bval = nullTerminateString(val); + + String val2 = "riobo"; + int lenCol2 = nullTerminateString(val2).length; + byte[] bval2 = nullTerminateString(val2); + + String val3 = "1992-01-17"; + int lenCol3 = nullTerminateString(val3).length; + byte[] bval3 = nullTerminateString(val3); + + String val4 = "-87,61"; + int lenCol4 = nullTerminateString(val4).length; + byte[] bval4 = nullTerminateString(val4); + + tLen = 4 + 2 + 4 + bval.length + 4 + bval2.length + 4 + + bval3.length + 4 + bval4.length; + this.dataOutputStream_.writeByte('D'); + this.dataOutputStream_.writeInt(tLen); + this.dataOutputStream_.writeShort(num); + + this.dataOutputStream_.writeInt(lenCol); + this.dataOutputStream_.writeBytes(new String( + nullTerminateString(val))); + + this.dataOutputStream_.writeInt(lenCol2); + this.dataOutputStream_.writeBytes(new String( + nullTerminateString(val2))); + + // Returns Bad value for type date : 1992-01-17 + + this.dataOutputStream_.writeInt(lenCol3); + this.dataOutputStream_.writeBytes(new String( + nullTerminateString(val3))); + + // Returns Bad value for type date too + + this.dataOutputStream_.writeInt(lenCol4); + + this.dataOutputStream_.writeBytes(new String( + nullTerminateString(val4))); + } + } catch (IOException e) { + System.out.println("Error in sendData: "); + e.printStackTrace(); } } @@ -209,183 +217,236 @@ private byte[] nullTerminateString(String string) { /** * - * @throws IOException */ - public void sendServerVersionMessage() throws IOException { - String param = "server_version"; - String paramV = "9"; - - byte[] nameB = nullTerminateString(param); // PEACE OF SHIT NEEDS TO BE - // NULTERMINATED EVEN THOUGH DOCS - // DONT MENTION IT - byte[] valB = nullTerminateString(paramV); - - this.dataOutputStream_.writeByte('S'); - this.dataOutputStream_.writeInt(4 + nameB.length + valB.length); - this.dataOutputStream_.write(nameB); - this.dataOutputStream_.write(valB); + public void sendServerVersionMessage() { + try { + String param = "server_version"; + String paramV = "9"; + + byte[] nameB = nullTerminateString(param); // PEACE OF SHIT NEEDS TO + // BE + // NULTERMINATED EVEN THOUGH DOCS + // DONT MENTION IT + byte[] valB = nullTerminateString(paramV); + + this.dataOutputStream_.writeByte('S'); + this.dataOutputStream_.writeInt(4 + nameB.length + valB.length); + this.dataOutputStream_.write(nameB); + + this.dataOutputStream_.write(valB); + } catch (IOException e) { + System.out.println("Error in sendServerVersionMessage: "); + e.printStackTrace(); + } } /** * - * @throws IOException */ - public void sendReadyForQueryMessage() throws IOException { - this.dataOutputStream_.writeByte('Z'); - this.dataOutputStream_.writeInt(5); - this.dataOutputStream_.writeByte('I'); + public void sendReadyForQueryMessage() { + try { + this.dataOutputStream_.writeByte('Z'); + this.dataOutputStream_.writeInt(5); + + this.dataOutputStream_.writeByte('I'); + } catch (IOException e) { + System.out.println("Error in sendReadyForQueryMessage: "); + e.printStackTrace(); + } } /** * * @param columns - * @throws IOException */ - public void sendRowDescription(String[] columns) throws IOException { - short fieldsNo = (short) columns.length; - LinkedList bNameList = new LinkedList(); - // If the field can be identified as a column of a specific table, the - // object ID of the table; otherwise zero. - int identificator = 0; - // If the field can be identified as a column of a specific table, the - // attribute number of the column; otherwise zero. - short identificatorAtr = 0; - // The object ID of the field's data type. - int typeInd = 0; - // The data type size (see pg_type.typlen). Note that negative values - // denote variable-width types. - short typeLen = -2; - // The type modifier (see pg_attribute.atttypmod). The meaning of the - // modifier is type-specific. - int typeMod = -1; - // The format code being used for the field. Currently will be zero - // (text) or one (binary). In a RowDescription returned from the - // statement variant of Describe, the format code is not yet known and - // will always be zero. - short formatCode = 0; - - // Null terminate all column names - for (int i = 0; i < columns.length; i++) { - String name = columns[i]; - byte[] bName = nullTerminateString(name); - bNameList.add(bName); - } - - // FIXME: Why 8 and not 6? - int totalSize = 8; - - // calculate lenght of the of the message - for (int i = 0; i < columns.length; i++) { - totalSize += bNameList.get(i).length; - } - - // FIXME: Why 14 and not 18? - totalSize = totalSize + 14 * columns.length; - - this.dataOutputStream_.writeByte('T'); - this.dataOutputStream_.writeInt(totalSize); - this.dataOutputStream_.writeShort(fieldsNo); - - for (int i = 0; i < columns.length; i++) { - this.dataOutputStream_.writeBytes(new String(bNameList.get(i))); - this.dataOutputStream_.writeInt(identificator); - this.dataOutputStream_.writeShort(identificatorAtr); - this.dataOutputStream_.writeInt(typeInd); - this.dataOutputStream_.writeShort(typeLen); - this.dataOutputStream_.writeInt(typeMod); - this.dataOutputStream_.writeShort(formatCode); + public void sendRowDescription(String[] columns) { + try { + short fieldsNo = (short) columns.length; + LinkedList bNameList = new LinkedList(); + // If the field can be identified as a column of a specific table, + // the + // object ID of the table; otherwise zero. + int identificator = 0; + // If the field can be identified as a column of a specific table, + // the + // attribute number of the column; otherwise zero. + short identificatorAtr = 0; + // The object ID of the field's data type. + int typeInd = 0; + // The data type size (see pg_type.typlen). Note that negative + // values + // denote variable-width types. + short typeLen = -2; + // The type modifier (see pg_attribute.atttypmod). The meaning of + // the + // modifier is type-specific. + int typeMod = -1; + // The format code being used for the field. Currently will be zero + // (text) or one (binary). In a RowDescription returned from the + // statement variant of Describe, the format code is not yet known + // and + // will always be zero. + short formatCode = 0; + + // Null terminate all column names + for (int i = 0; i < columns.length; i++) { + String name = columns[i]; + byte[] bName = nullTerminateString(name); + bNameList.add(bName); + } + + // FIXME: Why 8 and not 6? + int totalSize = 8; + + // calculate lenght of the of the message + for (int i = 0; i < columns.length; i++) { + totalSize += bNameList.get(i).length; + } + + // FIXME: Why 14 and not 18? + totalSize = totalSize + 14 * columns.length; + + this.dataOutputStream_.writeByte('T'); + this.dataOutputStream_.writeInt(totalSize); + this.dataOutputStream_.writeShort(fieldsNo); + + for (int i = 0; i < columns.length; i++) { + this.dataOutputStream_.writeBytes(new String(bNameList.get(i))); + this.dataOutputStream_.writeInt(identificator); + this.dataOutputStream_.writeShort(identificatorAtr); + this.dataOutputStream_.writeInt(typeInd); + this.dataOutputStream_.writeShort(typeLen); + this.dataOutputStream_.writeInt(typeMod); + + this.dataOutputStream_.writeShort(formatCode); + } + } catch (IOException e) { + System.out.println("Error in sendRowDescription: "); + e.printStackTrace(); } } /** * - * @throws IOException */ - public void sendCommandCompleteMessage() throws IOException { - this.dataOutputStream_.writeByte('C'); - String tmp = "SELECT 1"; - this.dataOutputStream_.writeInt(4 + tmp.getBytes().length); - this.dataOutputStream_.write(tmp.getBytes()); + public void sendCommandCompleteMessage() { + try { + this.dataOutputStream_.writeByte('C'); + String tmp = "SELECT 1"; + this.dataOutputStream_.writeInt(4 + tmp.getBytes().length); + + this.dataOutputStream_.write(tmp.getBytes()); + } catch (IOException e) { + System.out.println("Error in sendCommandCompleteMessage: "); + e.printStackTrace(); + } } /** * * @param values - * @throws IOException */ - public void sendDataRow(String[] values) throws IOException { - // 4 bytes to communicate the lenght of the message + 2 bytes for the - // column numbers = 6 - int tLen = 6; - short num = (short) values.length; - LinkedList lenColList = new LinkedList(); - LinkedList bvalList = new LinkedList(); - byte[] val; - - // Sum the length of the column value - for (int i = 0; i < values.length; i++) { - val = nullTerminateString(values[i]); - lenColList.add(val.length); - bvalList.add(val); - // lenght of the value + 4 bytes to communicate the value lenght - tLen += val.length + 4; - } + public void sendDataRow(String[] values) { + try { + // 4 bytes to communicate the lenght of the message + 2 bytes for + // the + // column numbers = 6 + int tLen = 6; + short num = (short) values.length; + LinkedList lenColList = new LinkedList(); + LinkedList bvalList = new LinkedList(); + byte[] val; + + // Sum the length of the column value + for (int i = 0; i < values.length; i++) { + val = nullTerminateString(values[i]); + lenColList.add(val.length); + bvalList.add(val); + // lenght of the value + 4 bytes to communicate the value lenght + tLen += val.length + 4; + } - this.dataOutputStream_.writeByte('D'); - this.dataOutputStream_.writeInt(tLen); - this.dataOutputStream_.writeShort(num); + this.dataOutputStream_.writeByte('D'); + this.dataOutputStream_.writeInt(tLen); + this.dataOutputStream_.writeShort(num); - // for each value, send 4 bytes for the value lenght and n bytes for - // the value itself - for (int i = 0; i < values.length; i++) { - this.dataOutputStream_.writeInt(lenColList.get(i)); - this.dataOutputStream_.writeBytes(new String( - nullTerminateString(values[i]))); + // for each value, send 4 bytes for the value lenght and n bytes for + // the value itself + for (int i = 0; i < values.length; i++) { + this.dataOutputStream_.writeInt(lenColList.get(i)); + + this.dataOutputStream_.writeBytes(new String( + nullTerminateString(values[i]))); + } + } catch (IOException e) { + System.out.println("Error in sendDataRow: "); + e.printStackTrace(); } } /** * - * @throws IOException */ - public void flush() throws IOException { - this.dataOutputStream_.flush(); + public void flush() { + try { + this.dataOutputStream_.flush(); + } catch (IOException e) { + System.out.println("Error in flush: "); + e.printStackTrace(); + } } /** * - * @throws IOException */ - public void sendAuthenticationOkMessage() throws IOException { - this.dataOutputStream_.writeByte('R'); - this.dataOutputStream_.writeInt(8); - this.dataOutputStream_.writeInt(0); + public void sendAuthenticationOkMessage() { + try { + this.dataOutputStream_.writeByte('R'); + this.dataOutputStream_.writeInt(8); + this.dataOutputStream_.writeInt(0); + } catch (IOException e) { + System.out.println("Error in sendAuthenticationOkMessage: "); + e.printStackTrace(); + } } /** * - * @throws IOException */ - private void sendBindCompleteMessage() throws IOException { - this.dataOutputStream_.writeByte('2'); - this.dataOutputStream_.writeInt(4); + public void sendBindCompleteMessage() { + try { + this.dataOutputStream_.writeByte('2'); + this.dataOutputStream_.writeInt(4); + } catch (IOException e) { + System.out.println("Error in sendBindCompleteMessage: "); + e.printStackTrace(); + } } /** * - * @throws IOException */ - private void sendEmptyQueryResponseMessage() throws IOException { - this.dataOutputStream_.writeByte('I'); - this.dataOutputStream_.writeInt(4); + public void sendEmptyQueryResponseMessage() { + try { + this.dataOutputStream_.writeByte('I'); + this.dataOutputStream_.writeInt(4); + } catch (IOException e) { + System.out.println("Error in sendEmptyQueryResponseMessage: "); + e.printStackTrace(); + } } /** * * @throws IOException */ - private void sendTerminateMessage() throws IOException { - this.dataOutputStream_.writeByte('X'); - this.dataOutputStream_.writeInt(4); + public void sendTerminateMessage() { + try { + this.dataOutputStream_.writeByte('X'); + this.dataOutputStream_.writeInt(4); + } catch (IOException e) { + System.out.println("Error in sendTerminateMessage: "); + e.printStackTrace(); + } } } From 4db87b81bd2a6b2978b8c71d3a9d9c135799a670 Mon Sep 17 00:00:00 2001 From: Michele Castellana Date: Wed, 4 Dec 2013 15:51:54 +0100 Subject: [PATCH 08/37] Avoid stupid crashes of the client. --- src/com/etk/network/client/Client.java | 8 ++++---- src/com/etk/network/server/SessionHandler.java | 3 --- 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/src/com/etk/network/client/Client.java b/src/com/etk/network/client/Client.java index 1e14238..4469705 100644 --- a/src/com/etk/network/client/Client.java +++ b/src/com/etk/network/client/Client.java @@ -34,12 +34,12 @@ public Client() { System.out.println("1-Enter query"); System.out.println("2-Quit"); int option = 0; + try { option = Integer.parseInt(br_.readLine()); - } catch (IOException e1) { - // TODO Auto-generated catch block - e1.printStackTrace(); + } catch (NumberFormatException | IOException e1) { } + switch (option) { case 1: @@ -48,7 +48,6 @@ public Client() { try { query = br_.readLine(); } catch (IOException e) { - // TODO Auto-generated catch block e.printStackTrace(); } @@ -114,6 +113,7 @@ private Connection connectToDatabaseOrDie() { e.printStackTrace(); System.exit(1); } catch (SQLException e) { + System.out.println("Cannot establish a connection!"); e.printStackTrace(); System.exit(2); } diff --git a/src/com/etk/network/server/SessionHandler.java b/src/com/etk/network/server/SessionHandler.java index d2e5d67..9754cc8 100644 --- a/src/com/etk/network/server/SessionHandler.java +++ b/src/com/etk/network/server/SessionHandler.java @@ -27,8 +27,6 @@ public SessionHandler(Socket server) { } } - /* Data row incorrect, needs to be finished */ - public void run() { try { @@ -80,7 +78,6 @@ public void run() { // InputStream is = new // ByteArrayInputStream(inputString.getBytes("UTF-8")); // SELECTMain.parse(is); - /* * this is in case the server receive an empty query string and From 91699c769e024cbcc39ef5fffa26a529453ba567 Mon Sep 17 00:00:00 2001 From: Michele Castellana Date: Wed, 4 Dec 2013 16:49:20 +0100 Subject: [PATCH 09/37] Example interface for the parser (needs to be completed) --- src/com/etk/parser/Parser.java | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 src/com/etk/parser/Parser.java diff --git a/src/com/etk/parser/Parser.java b/src/com/etk/parser/Parser.java new file mode 100644 index 0000000..c8d4799 --- /dev/null +++ b/src/com/etk/parser/Parser.java @@ -0,0 +1,16 @@ +package com.etk.parser; + +public interface Parser { + /* + * Put definition of the methods we have to use here and please, put also + * javadocs to understand what methods do and what paremeters are used to. + * For instance: + */ + /** + * this method do this, this, and this + * + * @param b + * represent the integer to do this this and this + */ + public void foo(int b); +} From 6a0d92315b0ed1e5075ef5b5eccb92f613e4eec5 Mon Sep 17 00:00:00 2001 From: Michele Castellana Date: Wed, 4 Dec 2013 23:29:29 +0100 Subject: [PATCH 10/37] Added a method to send an error message to the client. Added Javadocs --- src/com/etk/network/server/Sender.java | 29 +++++++++++++++++++++++--- 1 file changed, 26 insertions(+), 3 deletions(-) diff --git a/src/com/etk/network/server/Sender.java b/src/com/etk/network/server/Sender.java index 63646f6..46e5796 100644 --- a/src/com/etk/network/server/Sender.java +++ b/src/com/etk/network/server/Sender.java @@ -25,7 +25,29 @@ public void sendParseCompleteMessage() { } } + + /** + * send an error message to the client + * + * @param error + * the error to report to the client + */ + public void sendErrorResponse(String error) { + try { + this.dataOutputStream_.writeByte('E'); + byte[] temp = this.nullTerminateString(error); + this.dataOutputStream_.writeInt(temp.length + 4 + 1); + // you can find all types of messages here: + // http://www.postgresql.org/docs/9.3/static/protocol-error-fields.html + this.dataOutputStream_.writeByte('S'); + this.dataOutputStream_.write(temp); + } catch (IOException e) { + System.out.println("Error in sendErrorResponse: "); + e.printStackTrace(); + } + } + /** * */ @@ -203,7 +225,8 @@ private void sendData() { /** * * @param string - * @return + * the string that needs to be null terminated + * @return a array of bytes representing the string and the terminator */ private byte[] nullTerminateString(String string) { byte[] in = string.getBytes(); @@ -216,7 +239,7 @@ private byte[] nullTerminateString(String string) { } /** - * + * Send the server version to the client */ public void sendServerVersionMessage() { try { @@ -241,7 +264,7 @@ public void sendServerVersionMessage() { } /** - * + * Send a message to tell the client that the server is waiting for a query */ public void sendReadyForQueryMessage() { try { From e57ad2595e9104198496fe7124890ef4eaf4953f Mon Sep 17 00:00:00 2001 From: Michele Castellana Date: Wed, 4 Dec 2013 23:30:48 +0100 Subject: [PATCH 11/37] FIX: sendCommandCompleteMessage method --- src/com/etk/network/server/Sender.java | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/com/etk/network/server/Sender.java b/src/com/etk/network/server/Sender.java index 46e5796..7d7acb1 100644 --- a/src/com/etk/network/server/Sender.java +++ b/src/com/etk/network/server/Sender.java @@ -355,10 +355,9 @@ public void sendRowDescription(String[] columns) { public void sendCommandCompleteMessage() { try { this.dataOutputStream_.writeByte('C'); - String tmp = "SELECT 1"; - this.dataOutputStream_.writeInt(4 + tmp.getBytes().length); - - this.dataOutputStream_.write(tmp.getBytes()); + byte[] tmp = this.nullTerminateString("SELECT 1"); + this.dataOutputStream_.writeInt(4 + tmp.length); + this.dataOutputStream_.write(tmp); } catch (IOException e) { System.out.println("Error in sendCommandCompleteMessage: "); e.printStackTrace(); From e2fdfb348bf2f2d30a94e7d610e16417297b3763 Mon Sep 17 00:00:00 2001 From: Michele Castellana Date: Wed, 4 Dec 2013 23:34:05 +0100 Subject: [PATCH 12/37] FIX: now the server perfectly receive the query from the client --- src/com/etk/network/server/SessionHandler.java | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/src/com/etk/network/server/SessionHandler.java b/src/com/etk/network/server/SessionHandler.java index 9754cc8..21f8b47 100644 --- a/src/com/etk/network/server/SessionHandler.java +++ b/src/com/etk/network/server/SessionHandler.java @@ -42,10 +42,10 @@ public void run() { byte[] authParamsB = new byte[msgLen - 8]; // msglen - version and // len dataInputStream.read(authParamsB); - // String authParams = msgParser.parseMsg(authParamsB); + String authParams = msgParser.parseMsg(authParamsB); System.out.println("Client connected!"); - // System.out.println("Msg len: " + msgLen); + System.out.println("Msg len: " + msgLen); System.out.println("Protocol: V" + protocolMajorVersion + "." + protocolMinorVersion); @@ -59,10 +59,16 @@ public void run() { // if (dataInputStream.available() > 0) { byte type = dataInputStream.readByte(); int msgLength = dataInputStream.readInt(); + // remove the terminator of the first empty string + dataInputStream.readByte(); System.out.println("Message Type: " + (char) type); System.out.println("Lenght: " + msgLength); - - byte[] buf = new byte[dataInputStream.available() - 4]; + + // - 4 for the message lenght, - 1 for the terminator of the first + // string + // - 1 for the terminator of the first string, - 2 for the number of + // parameter + byte[] buf = new byte[msgLength - 4 - 1 - 1 - 2]; dataInputStream.read(buf); String inputString = msgParser.parseMsg(buf); System.out.println(inputString); From 98e3f86b527cdcb98c89a625f1c7626cc390e7ba Mon Sep 17 00:00:00 2001 From: supervitis Date: Thu, 5 Dec 2013 04:30:19 +0100 Subject: [PATCH 13/37] Connected DBMS, fails on parser. Needs interface --- src/com/etk/network/server/Sender.java | 15 +++--- .../etk/network/server/SessionHandler.java | 53 ++++++++++++++----- src/com/etk/parser/Parser.java | 7 +++ src/com/etk/parser/SELECTParser.java | 2 +- 4 files changed, 56 insertions(+), 21 deletions(-) diff --git a/src/com/etk/network/server/Sender.java b/src/com/etk/network/server/Sender.java index 7d7acb1..caaf393 100644 --- a/src/com/etk/network/server/Sender.java +++ b/src/com/etk/network/server/Sender.java @@ -3,6 +3,7 @@ import java.io.DataOutputStream; import java.io.IOException; import java.util.LinkedList; +import java.util.List; public class Sender { @@ -366,22 +367,22 @@ public void sendCommandCompleteMessage() { /** * - * @param values + * @param list */ - public void sendDataRow(String[] values) { + public void sendDataRow(List list) { try { // 4 bytes to communicate the lenght of the message + 2 bytes for // the // column numbers = 6 int tLen = 6; - short num = (short) values.length; + short num = (short) list.size(); LinkedList lenColList = new LinkedList(); LinkedList bvalList = new LinkedList(); byte[] val; // Sum the length of the column value - for (int i = 0; i < values.length; i++) { - val = nullTerminateString(values[i]); + for (int i = 0; i < list.size(); i++) { + val = nullTerminateString(list.get(i)); lenColList.add(val.length); bvalList.add(val); // lenght of the value + 4 bytes to communicate the value lenght @@ -394,11 +395,11 @@ public void sendDataRow(String[] values) { // for each value, send 4 bytes for the value lenght and n bytes for // the value itself - for (int i = 0; i < values.length; i++) { + for (int i = 0; i < list.size(); i++) { this.dataOutputStream_.writeInt(lenColList.get(i)); this.dataOutputStream_.writeBytes(new String( - nullTerminateString(values[i]))); + nullTerminateString(list.get(i)))); } } catch (IOException e) { System.out.println("Error in sendDataRow: "); diff --git a/src/com/etk/network/server/SessionHandler.java b/src/com/etk/network/server/SessionHandler.java index 21f8b47..1c97c86 100644 --- a/src/com/etk/network/server/SessionHandler.java +++ b/src/com/etk/network/server/SessionHandler.java @@ -9,7 +9,13 @@ import java.net.Socket; import java.nio.ByteBuffer; import java.util.Arrays; +import java.util.Collection; +import java.util.Iterator; +import java.util.List; +import java.util.ListIterator; +import com.etk.db.DBMSExecutor; +import com.etk.db.query.QueryResult; import com.etk.parser.SelectObject; import com.etk.parser.SelectQueryToObject; @@ -63,7 +69,7 @@ public void run() { dataInputStream.readByte(); System.out.println("Message Type: " + (char) type); System.out.println("Lenght: " + msgLength); - + // - 4 for the message lenght, - 1 for the terminator of the first // string // - 1 for the terminator of the first string, - 2 for the number of @@ -72,15 +78,19 @@ public void run() { dataInputStream.read(buf); String inputString = msgParser.parseMsg(buf); System.out.println(inputString); - InputStream is = new ByteArrayInputStream( - inputString.getBytes("UTF-8")); - SelectQueryToObject transform = new SelectQueryToObject(is); - SelectObject selectObject = transform.getSelectObject(); - - System.out.println("Parser found tables: " - + selectObject.getTableNames().toString() - + "\nParser found columns: " - + selectObject.getColumnNames().toString()); + + sender_.sendErrorResponse("Hello World"); + + // InputStream is = new ByteArrayInputStream( + // inputString.getBytes("UTF-8")); + // SelectQueryToObject transform = new SelectQueryToObject(is); + // SelectObject selectObject = transform.getSelectObject(); + // + // System.out.println("Parser found tables: " + // + selectObject.getTableNames().toString() + // + "\nParser found columns: " + // + selectObject.getColumnNames().toString()); + // InputStream is = new // ByteArrayInputStream(inputString.getBytes("UTF-8")); // SELECTMain.parse(is); @@ -92,12 +102,29 @@ public void run() { * dataOutputStream.flush(); */ + DBMSExecutor dbmsExecutor = new DBMSExecutor() { + + @Override + public List executeQuery(String sqlQuery) { + // TODO Auto-generated method stub + return null; + } + }; + + List queryResultList = dbmsExecutor + .executeQuery(inputString); + + // getColumnNames from parser + String[] columns = { "name", "surname" }; this.sender_.sendRowDescription(columns); - String[] values = { "david", "riobo" }; - this.sender_.sendDataRow(values); - this.sender_.flush(); + for (int i = 0; i < queryResultList.size(); i++) { + QueryResult queryResult = queryResultList.get(i); + // String[] values = { "david", "riobo" }; + this.sender_.sendDataRow(queryResult.getAttributes()); + this.sender_.flush(); + } this.sender_.sendCommandCompleteMessage(); this.sender_.sendReadyForQueryMessage(); this.sender_.flush(); diff --git a/src/com/etk/parser/Parser.java b/src/com/etk/parser/Parser.java index c8d4799..e7bf8a5 100644 --- a/src/com/etk/parser/Parser.java +++ b/src/com/etk/parser/Parser.java @@ -6,6 +6,13 @@ public interface Parser { * javadocs to understand what methods do and what paremeters are used to. * For instance: */ + + /*We need 3 methods here: + Access to selectObject.getColumnNames() + Check correctness + Access to the errors if the column names are wrong or if the query is bad*/ + + /** * this method do this, this, and this * diff --git a/src/com/etk/parser/SELECTParser.java b/src/com/etk/parser/SELECTParser.java index 381f963..89e1d3c 100644 --- a/src/com/etk/parser/SELECTParser.java +++ b/src/com/etk/parser/SELECTParser.java @@ -12,7 +12,7 @@ import java.util.List; @SuppressWarnings({"all", "warnings", "unchecked", "unused", "cast"}) -public class SELECTParser extends Parser { +public class SELECTParser extends Parser{ protected static final DFA[] _decisionToDFA; protected static final PredictionContextCache _sharedContextCache = new PredictionContextCache(); From 9bc71e690719208bc7dc993197cd7baf6eac5649 Mon Sep 17 00:00:00 2001 From: Georgy Shabunin Date: Sat, 7 Dec 2013 16:41:48 +0100 Subject: [PATCH 14/37] Parser integration #1 test --- src/com/etk/network/client/Client.java | 4 +- .../etk/network/server/SessionHandler.java | 577 +++++++++++++----- src/com/etk/parser/Parser.java | 23 - src/com/etk/parser/ParserInterface.java | 12 + src/com/etk/parser/SelectObject.java | 2 +- src/com/etk/parser/SelectQueryToObject.java | 1 + 6 files changed, 426 insertions(+), 193 deletions(-) delete mode 100644 src/com/etk/parser/Parser.java create mode 100644 src/com/etk/parser/ParserInterface.java diff --git a/src/com/etk/network/client/Client.java b/src/com/etk/network/client/Client.java index 4469705..1fefbf4 100644 --- a/src/com/etk/network/client/Client.java +++ b/src/com/etk/network/client/Client.java @@ -37,7 +37,7 @@ public Client() { try { option = Integer.parseInt(br_.readLine()); - } catch (NumberFormatException | IOException e1) { + } catch (IOException e1) { } switch (option) { @@ -79,7 +79,7 @@ private void query(Connection conn, ArrayList list, String query) { try { Statement st = conn.createStatement(); // the syntax for FROM is schema.table - ResultSet rs = st.executeQuery("SELECT id FROM student.student"); + ResultSet rs = st.executeQuery("SELECT id, name, surname FROM student"); while (rs.next()) { String name = rs.getString("name"); System.out.println(name); diff --git a/src/com/etk/network/server/SessionHandler.java b/src/com/etk/network/server/SessionHandler.java index 1c97c86..c3fdb7a 100644 --- a/src/com/etk/network/server/SessionHandler.java +++ b/src/com/etk/network/server/SessionHandler.java @@ -1,167 +1,410 @@ -package com.etk.network.server; - -import java.io.ByteArrayInputStream; -import java.io.DataInputStream; -import java.io.DataOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.UnsupportedEncodingException; -import java.net.Socket; -import java.nio.ByteBuffer; -import java.util.Arrays; -import java.util.Collection; -import java.util.Iterator; -import java.util.List; -import java.util.ListIterator; - -import com.etk.db.DBMSExecutor; -import com.etk.db.query.QueryResult; -import com.etk.parser.SelectObject; -import com.etk.parser.SelectQueryToObject; - -class SessionHandler implements Runnable { - private Socket server_; - private Sender sender_; - - public SessionHandler(Socket server) { - this.server_ = server; - try { - this.sender_ = new Sender(new DataOutputStream( - server_.getOutputStream())); - } catch (IOException e) { - e.printStackTrace(); - } - } - - public void run() { - - try { - DataInputStream dataInputStream = new DataInputStream( - server_.getInputStream()); - - MsgParser msgParser = new MsgParser(); - - int msgLen = dataInputStream.readInt(); - short protocolMajorVersion = dataInputStream.readShort(); - short protocolMinorVersion = dataInputStream.readShort(); - - byte[] authParamsB = new byte[msgLen - 8]; // msglen - version and - // len - dataInputStream.read(authParamsB); - String authParams = msgParser.parseMsg(authParamsB); - - System.out.println("Client connected!"); - System.out.println("Msg len: " + msgLen); - System.out.println("Protocol: V" + protocolMajorVersion + "." - + protocolMinorVersion); - - // System.out.println("Auth params: " + authParams); - - this.sender_.sendAuthenticationOkMessage(); - this.sender_.sendServerVersionMessage(); - this.sender_.sendReadyForQueryMessage(); - this.sender_.flush(); - - // if (dataInputStream.available() > 0) { - byte type = dataInputStream.readByte(); - int msgLength = dataInputStream.readInt(); - // remove the terminator of the first empty string - dataInputStream.readByte(); - System.out.println("Message Type: " + (char) type); - System.out.println("Lenght: " + msgLength); - - // - 4 for the message lenght, - 1 for the terminator of the first - // string - // - 1 for the terminator of the first string, - 2 for the number of - // parameter - byte[] buf = new byte[msgLength - 4 - 1 - 1 - 2]; - dataInputStream.read(buf); - String inputString = msgParser.parseMsg(buf); - System.out.println(inputString); - - sender_.sendErrorResponse("Hello World"); - - // InputStream is = new ByteArrayInputStream( - // inputString.getBytes("UTF-8")); - // SelectQueryToObject transform = new SelectQueryToObject(is); - // SelectObject selectObject = transform.getSelectObject(); - // - // System.out.println("Parser found tables: " - // + selectObject.getTableNames().toString() - // + "\nParser found columns: " - // + selectObject.getColumnNames().toString()); - - // InputStream is = new - // ByteArrayInputStream(inputString.getBytes("UTF-8")); - // SELECTMain.parse(is); - - /* - * this is in case the server receive an empty query string and - * seems to work sendEmptyQueryResponseMessage(dataOutputStream); - * sendReadyForQueryMessage(dataOutputStream); - * dataOutputStream.flush(); - */ - - DBMSExecutor dbmsExecutor = new DBMSExecutor() { - - @Override - public List executeQuery(String sqlQuery) { - // TODO Auto-generated method stub - return null; - } - }; - - List queryResultList = dbmsExecutor - .executeQuery(inputString); - - // getColumnNames from parser - - String[] columns = { "name", "surname" }; - this.sender_.sendRowDescription(columns); - - for (int i = 0; i < queryResultList.size(); i++) { - QueryResult queryResult = queryResultList.get(i); - // String[] values = { "david", "riobo" }; - this.sender_.sendDataRow(queryResult.getAttributes()); - this.sender_.flush(); - } - this.sender_.sendCommandCompleteMessage(); - this.sender_.sendReadyForQueryMessage(); - this.sender_.flush(); - - // reply to the client msg, delete exit - // } - - } catch (IOException ioe) { - System.out.println("IOException on socket listen: " + ioe); - ioe.printStackTrace(); - } catch (Exception e) { - e.printStackTrace(); - } - } - - private class MsgParser { - - public short parseShort(byte[] bytes) { - byte[] typeBytes = new byte[2]; - typeBytes[0] = 0; - typeBytes[1] = bytes[0]; - return ByteBuffer.wrap(typeBytes).getShort(); - - } - - public int parseInt(byte[] bytes) { - byte[] lenBytes = Arrays.copyOf(bytes, 4); - int len = ByteBuffer.wrap(lenBytes).getInt(); - return len; - } - - public String parseMsg(byte[] bytes) - throws UnsupportedEncodingException { - String msgString = new String(bytes, "UTF-8"); - return msgString; - } - - } - -} +package com.etk.network.server; + +import java.io.*; +import java.net.Socket; +import java.nio.ByteBuffer; +import java.util.Arrays; + +import com.etk.parser.SelectObject; +import com.etk.parser.SelectQueryToObject; + +class SessionHandler implements Runnable { + private Socket server_; + private String line_, input_; + + SessionHandler(Socket server) { + this.server_ = server; + } + + private byte[] nullTerminateString(String string) { + byte[] in = string.getBytes(); + byte[] out = new byte[in.length + 1]; + for (int i = 0; i < in.length; i++) { + out[i] = in[i]; + } + out[in.length] = 0; + return out; + } + + private void sendServerVersionMessage(DataOutputStream dataOutputStream) + throws IOException { + String param = "server_version"; + String paramV = "9"; + + byte[] nameB = nullTerminateString(param); // PEACE OF SHIT NEEDS TO BE + // NULTERMINATED EVEN THOUGH DOCS + // DONT MENTION IT + byte[] valB = nullTerminateString(paramV); + + dataOutputStream.writeByte('S'); + dataOutputStream.writeInt(4 + nameB.length + valB.length); + dataOutputStream.write(nameB); + dataOutputStream.write(valB); + } + + private void sendAuthenticationOkMessage(DataOutputStream dataOutputStream) + throws IOException { + dataOutputStream.writeByte('R'); + dataOutputStream.writeInt(8); + dataOutputStream.writeInt(0); + } + + private void sendReadyForQueryMessage(DataOutputStream dataOutputStream) + throws IOException { + dataOutputStream.writeByte('Z'); + dataOutputStream.writeInt(5); + dataOutputStream.writeByte('I'); + } + + private void sendTerminateMessage(DataOutputStream dataOutputStream) + throws IOException { + dataOutputStream.writeByte('X'); + dataOutputStream.writeInt(4); + } + + private void sendCommandCompleteMessage(DataOutputStream dataOutputStream) + throws IOException { + dataOutputStream.writeByte('C'); + String tmp = "SELECT 1"; + dataOutputStream.writeInt(4 + tmp.getBytes().length); + dataOutputStream.write(tmp.getBytes()); + } + + private void sendParseCompleteMessage(DataOutputStream dataOutputStream) + throws IOException { + dataOutputStream.writeByte('1'); + dataOutputStream.writeInt(4); + } + + private void sendBindCompleteMessage(DataOutputStream dataOutputStream) + throws IOException { + dataOutputStream.writeByte('2'); + dataOutputStream.writeInt(4); + } + + private void sendEmptyQueryResponseMessage(DataOutputStream dataOutputStream) + throws IOException { + dataOutputStream.writeByte('I'); + dataOutputStream.writeInt(4); + } + + private void sendRowDescriptionMessage(DataOutputStream dataOutputStream) + throws IOException { + dataOutputStream.writeByte('T'); + dataOutputStream.writeInt(27); + dataOutputStream.writeShort(1); + dataOutputStream.writeBytes("id"); + dataOutputStream.writeInt(32780); + dataOutputStream.writeShort(3); + dataOutputStream.writeInt(20); + dataOutputStream.writeShort(8); + dataOutputStream.writeInt(-1); + dataOutputStream.writeShort(0); + + } + + /* Data row incorrect, needs to be finished */ + + private void sendDataRowMessage(DataOutputStream dataOutputStream) { + try { + dataOutputStream.writeByte('D'); + // Problem with upper line, after that it brokes (tried with other + // types of write after it). Why? Problem of size? + // Tried wireshark, it sends ACK FIN + dataOutputStream.writeInt(11); + dataOutputStream.writeShort(1); + dataOutputStream.writeInt(1); + dataOutputStream.writeByte('1'); + } catch (IOException ioe) { + System.out.println(ioe); + } + } + + public void run() { + + input_ = ""; + + try { + DataInputStream dataInputStream = new DataInputStream( + server_.getInputStream()); + DataOutputStream dataOutputStream = new DataOutputStream( + server_.getOutputStream()); + + MsgParser msgParser = new MsgParser(); + + int msgLen = dataInputStream.readInt(); + short protocolMajorVersion = dataInputStream.readShort(); + short protocolMinorVersion = dataInputStream.readShort(); + + byte[] authParamsB = new byte[msgLen - 8]; // msglen - version and + // len + dataInputStream.read(authParamsB); + // String authParams = msgParser.parseMsg(authParamsB); + + System.out.println("Client connected!"); + // System.out.println("Msg len: " + msgLen); + System.out.println("Protocol: V" + protocolMajorVersion + "." + + protocolMinorVersion); + + // System.out.println("Auth params: " + authParams); + + sendAuthenticationOkMessage(dataOutputStream); + + /* + * os.writeByte('K'); os.writeInt(12); os.writeInt(2); + * os.writeInt(3); + */ + + this.sendServerVersionMessage(dataOutputStream); + + this.sendReadyForQueryMessage(dataOutputStream); + + dataOutputStream.flush(); + + /* + * I think now the client wants the result of the query + */ + + // if (dataInputStream.available() > 0) { + byte type = dataInputStream.readByte(); + int msgLength = dataInputStream.readInt(); + System.out.println("Message Type: " + (char) type); + System.out.println("Lenght: " + msgLength); + + byte[] buf = new byte[dataInputStream.available() - 4]; + dataInputStream.read(buf); + String inputString = msgParser.parseMsg(buf); + System.out.println(inputString); + InputStream is = new + ByteArrayInputStream(inputString.getBytes("UTF-8")); + + //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + //Actual parsing of query and creation of selectObject which contains the query data: + SelectQueryToObject selectQueryToObject = new SelectQueryToObject(is); + SelectObject selectObject = selectQueryToObject.getSelectObject(); + + //just for understanding of how to use selectObject: + for(String columnName : selectObject.getColumnNames()){ + System.out.println("Column: " + columnName); + } + + for(String tableName : selectObject.getTableNames()){ + System.out.println("Table: " + tableName); + } + + /* + * this is in case the server receive an empty query string and + * seems to work sendEmptyQueryResponseMessage(dataOutputStream); + * sendReadyForQueryMessage(dataOutputStream); + * dataOutputStream.flush(); + */ + + sendData(dataOutputStream); + dataOutputStream.flush(); + + sendCommandCompleteMessage(dataOutputStream); + sendReadyForQueryMessage(dataOutputStream); + dataOutputStream.flush(); + + // reply to the client msg, delete exit + // } + + } catch (IOException ioe) { + System.out.println("IOException on socket listen: " + ioe); + ioe.printStackTrace(); + } catch (Exception e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + + private void sendData(DataOutputStream dataOutputStream) throws IOException { + /* + * RowDescription (B) Byte1('T') Identifies the message as a row + * description. Int32 Length of message contents in bytes, including + * self. Int16 Specifies the number of fields in a row (may be zero). + * Then, for each field, there is the following: String The field name. + * Int32 If the field can be identified as a column of a specific table, + * the object ID of the table; otherwise zero. Int16 If the field can be + * identified as a column of a specific table, the attribute number of + * the column; otherwise zero. Int32 The object ID of the field's data + * type. Int16 The data type size (see pg_type.typlen). Note that + * negative values denote variable-width types. Int32 The type modifier + * (see pg_attribute.atttypmod). The meaning of the modifier is + * type-specific. Int16 The format code being used for the field. + * Currently will be zero (text) or one (binary). In a RowDescription + * returned from the statement variant of Describe, the format code is + * not yet known and will always be zero. + * + * SSLRequest (F) + */ + + short fieldsNo = 4; + + String name = "name"; + byte[] bName = nullTerminateString(name); + int identificator = 0; + short identificatorAtr = 0; + int typeInd = 0; + short typeLen = -2; + int typeMod = -1; + short formatCode = 0; + + String name2 = "surname"; + byte[] bName2 = nullTerminateString(name2); + int identificator2 = 0; + short identificatorAtr2 = 0; + int typeInd2 = 0; + short typeLen2 = -2; + int typeMod2 = -1; + short formatCode2 = 0; + + String name3 = "date"; + byte[] bName3 = nullTerminateString(name3); + int identificator3 = 0; + short identificatorAtr3 = 0; + int typeInd3 = 0; + short typeLen3 = -2; + int typeMod3 = -1; + short formatCode3 = 0; + + String name4 = "number"; + byte[] bName4 = nullTerminateString(name4); + int identificator4 = 0; + short identificatorAtr4 = 0; + int typeInd4 = 0; + short typeLen4 = -2; + int typeMod4 = -1; + short formatCode4 = 0; + + int totalSize = bName.length + 4 + 2 + 4 + 2 + 4 + 2 + 4 + + bName3.length + 4 + 2 + 4 + 2 + 2 + bName4.length + 4 + 2 + 4 + + 2 + 2; + + dataOutputStream.writeByte('T'); + dataOutputStream.writeInt(totalSize); + dataOutputStream.writeShort(fieldsNo); + + dataOutputStream.writeBytes(new String(bName)); + dataOutputStream.writeInt(identificator); + dataOutputStream.writeShort(identificatorAtr); + dataOutputStream.writeInt(typeInd); + dataOutputStream.writeShort(typeLen); + dataOutputStream.writeInt(typeMod); + dataOutputStream.writeShort(formatCode); + + dataOutputStream.writeBytes(new String(bName2)); + dataOutputStream.writeInt(identificator2); + dataOutputStream.writeShort(identificatorAtr2); + dataOutputStream.writeInt(typeInd2); + dataOutputStream.writeShort(typeLen2); + dataOutputStream.writeInt(typeMod2); + dataOutputStream.writeShort(formatCode2); + + dataOutputStream.writeBytes(new String(bName3)); + dataOutputStream.writeInt(identificator3); + dataOutputStream.writeShort(identificatorAtr3); + dataOutputStream.writeInt(typeInd3); + dataOutputStream.writeShort(typeLen3); + dataOutputStream.writeInt(typeMod3); + dataOutputStream.writeShort(formatCode3); + + dataOutputStream.writeBytes(new String(bName4)); + dataOutputStream.writeInt(identificator4); + dataOutputStream.writeShort(identificatorAtr4); + dataOutputStream.writeInt(typeInd4); + dataOutputStream.writeShort(typeLen4); + dataOutputStream.writeInt(typeMod4); + dataOutputStream.writeShort(formatCode4); + + /* + * Byte1('D') Identifies the message as a data row. + * + * Int32 Length of message contents in bytes, including self. + * + * Int16 The number of column values that follow (possibly zero). + * + * Next, the following pair of fields appear for each column: + * + * Int32 The length of the column value, in bytes (this count does not + * include itself). Can be zero. As a special case, -1 indicates a NULL + * column value. No value bytes follow in the NULL case. + * + * Byten The value of the column, in the format indicated by the + * associated format code. n is the above lengt + */ + + for ( int i = 0; i < 2; i++){ + + int tLen = 0; + short num = 4; + + String val = "david"; + int lenCol = nullTerminateString(val).length; + byte[] bval = nullTerminateString(val); + + String val2 = "riobo"; + int lenCol2 = nullTerminateString(val2).length; + byte[] bval2 = nullTerminateString(val2); + + String val3 = "1992-01-17"; + int lenCol3 = nullTerminateString(val3).length; + byte[] bval3 = nullTerminateString(val3); + + String val4 = "-87,61"; + int lenCol4 = nullTerminateString(val4).length; + byte[] bval4 = nullTerminateString(val4); + + tLen = 4 + 2 + 4 + bval.length + 4 + bval2.length + 4 + bval3.length + + 4 + bval4.length; + dataOutputStream.writeByte('D'); + dataOutputStream.writeInt(tLen); + dataOutputStream.writeShort(num); + + dataOutputStream.writeInt(lenCol); + dataOutputStream.writeBytes(new String(nullTerminateString(val))); + + dataOutputStream.writeInt(lenCol2); + dataOutputStream.writeBytes(new String(nullTerminateString(val2))); + + // Returns Bad value for type date : 1992-01-17 + + dataOutputStream.writeInt(lenCol3); + dataOutputStream.writeBytes(new String(nullTerminateString(val3))); + + // Returns Bad value for type date too + + dataOutputStream.writeInt(lenCol4); + dataOutputStream.writeBytes(new String(nullTerminateString(val4))); + + } + + dataOutputStream.flush(); + + } + + private class MsgParser { + + public short parseShort(byte[] bytes) { + byte[] typeBytes = new byte[2]; + typeBytes[0] = 0; + typeBytes[1] = bytes[0]; + return ByteBuffer.wrap(typeBytes).getShort(); + + } + + public int parseInt(byte[] bytes) { + byte[] lenBytes = Arrays.copyOf(bytes, 4); + int len = ByteBuffer.wrap(lenBytes).getInt(); + return len; + } + + public String parseMsg(byte[] bytes) + throws UnsupportedEncodingException { + String msgString = new String(bytes, "UTF-8"); + return msgString; + } + + } + +} diff --git a/src/com/etk/parser/Parser.java b/src/com/etk/parser/Parser.java deleted file mode 100644 index e7bf8a5..0000000 --- a/src/com/etk/parser/Parser.java +++ /dev/null @@ -1,23 +0,0 @@ -package com.etk.parser; - -public interface Parser { - /* - * Put definition of the methods we have to use here and please, put also - * javadocs to understand what methods do and what paremeters are used to. - * For instance: - */ - - /*We need 3 methods here: - Access to selectObject.getColumnNames() - Check correctness - Access to the errors if the column names are wrong or if the query is bad*/ - - - /** - * this method do this, this, and this - * - * @param b - * represent the integer to do this this and this - */ - public void foo(int b); -} diff --git a/src/com/etk/parser/ParserInterface.java b/src/com/etk/parser/ParserInterface.java new file mode 100644 index 0000000..913d281 --- /dev/null +++ b/src/com/etk/parser/ParserInterface.java @@ -0,0 +1,12 @@ +package com.etk.parser; + +/** + * Created with IntelliJ IDEA. + * User: Georgy + * Date: 05.12.13 + * Time: 22:46 + * To change this template use File | Settings | File Templates. + */ +public interface ParserInterface { + +} diff --git a/src/com/etk/parser/SelectObject.java b/src/com/etk/parser/SelectObject.java index b7280b7..efe17fd 100644 --- a/src/com/etk/parser/SelectObject.java +++ b/src/com/etk/parser/SelectObject.java @@ -9,7 +9,7 @@ * Time: 21:17 * To change this template use File | Settings | File Templates. */ -public class SelectObject { +public class SelectObject implements ParserInterface { ArrayList columnNames; ArrayList tableNames; diff --git a/src/com/etk/parser/SelectQueryToObject.java b/src/com/etk/parser/SelectQueryToObject.java index 1a60d4d..3aa561e 100644 --- a/src/com/etk/parser/SelectQueryToObject.java +++ b/src/com/etk/parser/SelectQueryToObject.java @@ -4,6 +4,7 @@ import org.antlr.v4.runtime.CommonTokenStream; import org.antlr.v4.runtime.misc.NotNull; import org.antlr.v4.runtime.tree.ParseTree; + import org.antlr.v4.runtime.tree.ParseTreeWalker; import java.io.FileInputStream; From 8ead8d2515981a57bb5a9e3f47e9456e53381bca Mon Sep 17 00:00:00 2001 From: Mladen Subotic Date: Sun, 8 Dec 2013 18:33:07 +0100 Subject: [PATCH 15/37] selection clauses and expressions --- src/com/etk/data/DataSource.java | 7 ++-- src/com/etk/data/query/Expression.java | 23 ++++++++++++ src/com/etk/data/query/Operator.java | 13 +++++++ src/com/etk/data/query/Properties.java | 40 +++++++++++++++++++++ src/com/etk/data/query/SelectionClause.java | 27 ++++++++++++++ 5 files changed, 107 insertions(+), 3 deletions(-) create mode 100644 src/com/etk/data/query/Expression.java create mode 100644 src/com/etk/data/query/Operator.java create mode 100644 src/com/etk/data/query/Properties.java create mode 100644 src/com/etk/data/query/SelectionClause.java diff --git a/src/com/etk/data/DataSource.java b/src/com/etk/data/DataSource.java index 9369e1d..79f0ca1 100644 --- a/src/com/etk/data/DataSource.java +++ b/src/com/etk/data/DataSource.java @@ -1,5 +1,6 @@ package com.etk.data; +import com.etk.data.query.Properties; import com.etk.manager.schema.Attribute; import com.etk.manager.schema.Type; import com.etk.manager.schema.mappings.AttributeMapping; @@ -16,9 +17,9 @@ */ public interface DataSource { - public List getEntityCandidates(int limit, int offset, boolean label); - public List getAttributes(String entity, int limit, int offset, boolean label); + public List getEntityCandidates(Properties queryProperties); + public List getAttributes(String entity, Properties queryProperties); public List getType(String entity, String attribute); - public List getValues(String entity, String attributes[], int limit, int offset); + public List getValues(String entity, String attributes[], Properties queryProperties); public List getAvailableEndpoints(); } diff --git a/src/com/etk/data/query/Expression.java b/src/com/etk/data/query/Expression.java new file mode 100644 index 0000000..b724690 --- /dev/null +++ b/src/com/etk/data/query/Expression.java @@ -0,0 +1,23 @@ +package com.etk.data.query; + +import java.util.List; + +public class Expression { + private boolean negated; + private Operator operator; + List clauses; + + + public boolean isNegated() { + return negated; + } + public Operator getOperator() { + return operator; + } + public List getClauses() { + return clauses; + } + + + +} diff --git a/src/com/etk/data/query/Operator.java b/src/com/etk/data/query/Operator.java new file mode 100644 index 0000000..94ee7f4 --- /dev/null +++ b/src/com/etk/data/query/Operator.java @@ -0,0 +1,13 @@ +package com.etk.data.query; + +public enum Operator { + EQ, + LT, + GT, + LE, + GE, + LIKE, + AND, + OR + +} diff --git a/src/com/etk/data/query/Properties.java b/src/com/etk/data/query/Properties.java new file mode 100644 index 0000000..327674f --- /dev/null +++ b/src/com/etk/data/query/Properties.java @@ -0,0 +1,40 @@ +package com.etk.data.query; + +public class Properties { + private int limit; + private int offset; + private boolean label; + + public Properties(int limit, int offset, boolean label) { + this.offset = offset; + this.limit = limit; + this.label = label; + } + + public int getLimit() { + return limit; + } + + public void setLimit(int limit) { + this.limit = limit; + } + + public int getOffset() { + return offset; + } + + public void setOffset(int offset) { + this.offset = offset; + } + + public boolean isLabel() { + return label; + } + + public void setLabel(boolean label) { + this.label = label; + } + + + +} diff --git a/src/com/etk/data/query/SelectionClause.java b/src/com/etk/data/query/SelectionClause.java new file mode 100644 index 0000000..6c91108 --- /dev/null +++ b/src/com/etk/data/query/SelectionClause.java @@ -0,0 +1,27 @@ +package com.etk.data.query; + +public class SelectionClause { + private String attribute; + private Operator operator; + private Object value; + + public SelectionClause(String attribute, Operator oper, Object value) { + this.attribute = attribute; + this.operator = oper; + this.value = value; + } + + public String getAttribute() { + return attribute; + } + + public Operator getOperator() { + return operator; + } + + public Object getValue() { + return value; + } + + +} From 64ec01c1a275e07bcefb7f4c5cdfd0fba02af206 Mon Sep 17 00:00:00 2001 From: Mladen Subotic Date: Sun, 8 Dec 2013 18:51:36 +0100 Subject: [PATCH 16/37] moved negation from expressions to clauses --- src/com/etk/data/query/Expression.java | 8 ++++---- src/com/etk/data/query/SelectionClause.java | 4 +++- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/src/com/etk/data/query/Expression.java b/src/com/etk/data/query/Expression.java index b724690..d100265 100644 --- a/src/com/etk/data/query/Expression.java +++ b/src/com/etk/data/query/Expression.java @@ -3,14 +3,14 @@ import java.util.List; public class Expression { - private boolean negated; private Operator operator; List clauses; - - public boolean isNegated() { - return negated; + public Expression(Operator oper, List clauses) { + this.operator = oper; + this.clauses = clauses; } + public Operator getOperator() { return operator; } diff --git a/src/com/etk/data/query/SelectionClause.java b/src/com/etk/data/query/SelectionClause.java index 6c91108..52e74a7 100644 --- a/src/com/etk/data/query/SelectionClause.java +++ b/src/com/etk/data/query/SelectionClause.java @@ -4,11 +4,13 @@ public class SelectionClause { private String attribute; private Operator operator; private Object value; + private boolean negated; - public SelectionClause(String attribute, Operator oper, Object value) { + public SelectionClause(String attribute, Operator oper, Object value, boolean negated) { this.attribute = attribute; this.operator = oper; this.value = value; + this.negated = negated; } public String getAttribute() { From f2689ecff37e677e08a8cdf8606712f6552389a0 Mon Sep 17 00:00:00 2001 From: Mladen Subotic Date: Sun, 8 Dec 2013 22:40:38 +0100 Subject: [PATCH 17/37] init queryExec, moved init,offset,label to properties class --- src/com/etk/data/RemoteSourceRDF.java | 28 ++++-- src/com/etk/data/query/SelectionClause.java | 2 +- src/com/etk/db/DBMSExecutor.java | 3 +- src/com/etk/db/QueryExecutorImpl.java | 89 +++++++++++++++++++ src/com/etk/manager/SchemaManager.java | 2 +- src/com/etk/manager/schema/Schema.java | 14 +-- .../schema/{Table.java => UserTable.java} | 8 +- 7 files changed, 127 insertions(+), 19 deletions(-) create mode 100644 src/com/etk/db/QueryExecutorImpl.java rename src/com/etk/manager/schema/{Table.java => UserTable.java} (81%) diff --git a/src/com/etk/data/RemoteSourceRDF.java b/src/com/etk/data/RemoteSourceRDF.java index cd936ea..df4a683 100644 --- a/src/com/etk/data/RemoteSourceRDF.java +++ b/src/com/etk/data/RemoteSourceRDF.java @@ -3,6 +3,7 @@ import java.util.ArrayList; import java.util.List; +import com.etk.data.query.Properties; import com.hp.hpl.jena.query.Query; import com.hp.hpl.jena.query.QueryExecution; import com.hp.hpl.jena.query.QueryExecutionFactory; @@ -23,14 +24,14 @@ public RemoteSourceRDF( String service ){ } @Override - public List getEntityCandidates(int limit, int offset, boolean label) { + public List getEntityCandidates(Properties queryProperties) { String queryString = queryStringTemplate; queryString += "SELECT (COUNT(?o) as ?num) ?o WHERE { ?s a ?o. "; // Checks should the sparql query ask for a rdfs:label // This should be used only if you are sure that there is a predicate // rdfs:label in the data source - if( label ){ + if( queryProperties.isLabel() ){ queryString += "?o rdfs:label ?label. " + "FILTER (lang(?label) = 'en' || lang(?label) = '') "; } @@ -45,11 +46,11 @@ public List getEntityCandidates(int limit, int offset, boolean label) { //Add order by and sort by queryString += " GROUP BY ?o ORDER BY DESC(?num)"; - if( limit != 0 ){ - queryString += " LIMIT " + Integer.toString( limit ); + if( queryProperties.getLimit() != 0 ){ + queryString += " LIMIT " + Integer.toString( queryProperties.getLimit() ); } - if( offset != 0 ){ - queryString += " OFFSET " + Integer.toString( offset ); + if( queryProperties.getOffset() != 0 ){ + queryString += " OFFSET " + Integer.toString( queryProperties.getOffset() ); } @@ -60,7 +61,7 @@ public List getEntityCandidates(int limit, int offset, boolean label) { service, query ); ResultSet resultSet = queryExecution.execSelect(); - return entityCandidatesFromRS(resultSet, label); + return entityCandidatesFromRS(resultSet, queryProperties.isLabel()); } private List entityCandidatesFromRS(ResultSet resultSet, boolean label){ @@ -86,7 +87,11 @@ private List entityCandidatesFromRS(ResultSet resultSet, boolean label){ } @Override - public List getAttributes(String entity, int limit, int offset, boolean label){ + public List getAttributes(String entity, Properties queryProperties){ + boolean label = queryProperties.isLabel(); + int offset = queryProperties.getOffset(); + int limit = queryProperties.getLimit(); + String queryString = queryStringTemplate; queryString += "Select (count(?p) as ?num) ?p WHERE { ?s rdf:type/rdfs:subClassOf* <" + entity + ">." + " ?s ?p ?o." + @@ -158,8 +163,13 @@ public List getType(String entity, String attribute) { } @Override - public List getValues(String entity, String attributes[], int limit, int offset) { + public List getValues(String entity, String attributes[], Properties queryProperties) { String queryString = queryStringTemplate; + boolean label = queryProperties.isLabel(); + int offset = queryProperties.getOffset(); + int limit = queryProperties.getLimit(); + + queryString += "Select distinct ?s " + repeateString("?o", attributes.length) + " WHERE { ?s rdf:type/rdfs:subClassOf* <" + entity + ">."; diff --git a/src/com/etk/data/query/SelectionClause.java b/src/com/etk/data/query/SelectionClause.java index 52e74a7..04ec15e 100644 --- a/src/com/etk/data/query/SelectionClause.java +++ b/src/com/etk/data/query/SelectionClause.java @@ -16,7 +16,7 @@ public SelectionClause(String attribute, Operator oper, Object value, boolean ne public String getAttribute() { return attribute; } - + public Operator getOperator() { return operator; } diff --git a/src/com/etk/db/DBMSExecutor.java b/src/com/etk/db/DBMSExecutor.java index 8dd9339..8aa1f58 100644 --- a/src/com/etk/db/DBMSExecutor.java +++ b/src/com/etk/db/DBMSExecutor.java @@ -2,6 +2,7 @@ import com.etk.db.exceptions.RelsemDBException; import com.etk.db.query.QueryResult; +import com.etk.parser.SelectObject; import java.util.List; @@ -13,6 +14,6 @@ * To change this template use File | Settings | File Templates. */ public interface DBMSExecutor { - public List executeQuery(String sqlQuery) throws RelsemDBException; + public List executeQuery(SelectObject sqlQuery) throws RelsemDBException; } diff --git a/src/com/etk/db/QueryExecutorImpl.java b/src/com/etk/db/QueryExecutorImpl.java new file mode 100644 index 0000000..d84ab3a --- /dev/null +++ b/src/com/etk/db/QueryExecutorImpl.java @@ -0,0 +1,89 @@ +package com.etk.db; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import com.etk.data.DataSource; +import com.etk.data.ValueCandidate; +import com.etk.data.query.Properties; +import com.etk.db.exceptions.RelsemDBException; +import com.etk.db.query.QueryResult; +import com.etk.manager.schema.Attribute; +import com.etk.manager.schema.Schema; +import com.etk.manager.schema.UserTable; +import com.etk.parser.SelectObject; + +public class QueryExecutorImpl implements DBMSExecutor { + + private Schema schema; + private DataSource dataSource; + + + + + + @Override + public List executeQuery(SelectObject sqlQuery) + throws RelsemDBException { + + if(!validateQuery(sqlQuery)) { + //return empty, raise exception, whatever + System.out.println("Query validation failed!"); + return new ArrayList(); + } + + //create a map requested tables + List reqTables = sqlQuery.getTableNames(); + + //fill reqProjection + + Map> reqProjection = null; + Map> tableSelects = new HashMap<>(); //valueCandidates for table and projection + + for(String table : reqProjection.keySet()) { + List reqAttributes = reqProjection.get(table); + + String[] attrUris = new String[reqAttributes.size()]; + for(int i=0;i tables = schema.getTables(); + List queryTables = sqlQuery.getTableNames(); + + for(String qTable : queryTables) { + if(!schema.hasTable(qTable)) { +// throw new RelsemDBException("Table \""+qTable+"\" does not exist within user schema!""); + System.out.println("Table \""+qTable+"\" does not exist within user schema!"); + return false; + } + } + + //TODO fix vaidation based on tables of requested attributes + for(String qAttr : sqlQuery.getColumnNames()) { + } + + + + return true; + } + +} diff --git a/src/com/etk/manager/SchemaManager.java b/src/com/etk/manager/SchemaManager.java index eb0c576..c1772dd 100644 --- a/src/com/etk/manager/SchemaManager.java +++ b/src/com/etk/manager/SchemaManager.java @@ -1,7 +1,7 @@ package com.etk.manager; import com.etk.manager.schema.Schema; -import com.etk.manager.schema.Table; +import com.etk.manager.schema.UserTable; import java.util.HashMap; import java.util.List; diff --git a/src/com/etk/manager/schema/Schema.java b/src/com/etk/manager/schema/Schema.java index eff5675..3f512f7 100644 --- a/src/com/etk/manager/schema/Schema.java +++ b/src/com/etk/manager/schema/Schema.java @@ -12,18 +12,22 @@ */ public class Schema { private User owner; - private Map tables; + private Map tables; public Schema(User owner) { this.owner = owner; - this.tables = new HashMap(); + this.tables = new HashMap(); } - public Collection getTables() { + public boolean hasTable(String tableName) { + return tables.containsKey(tableName); + } + + public Collection getTables() { return tables.values(); } - public void addTable(Table table) { + public void addTable(UserTable table) { this.tables.put(table.getTableName(),table); } @@ -31,7 +35,7 @@ public void removeTable(String table) { this.tables.remove(table); } - public Table getTable(String name) { + public UserTable getTable(String name) { return tables.get(name); } diff --git a/src/com/etk/manager/schema/Table.java b/src/com/etk/manager/schema/UserTable.java similarity index 81% rename from src/com/etk/manager/schema/Table.java rename to src/com/etk/manager/schema/UserTable.java index 43df86b..378e401 100644 --- a/src/com/etk/manager/schema/Table.java +++ b/src/com/etk/manager/schema/UserTable.java @@ -9,19 +9,23 @@ /** * Created by mladen on 11/9/13. */ -public class Table { +public class UserTable { private String tableName; //mapping how? Map attributes; private String entityUri; private String entityLabel; - public Table(String name, String entityUri, String entityLabel) { + public UserTable(String name, String entityUri, String entityLabel) { this.tableName = name; this.entityUri = entityUri; this.entityLabel = entityLabel; this.attributes = new HashMap(); } + + public boolean hasAttribute(String attrName) { + return attributes.containsKey(attrName); + } public void addAttribute(Attribute attribute) { this.attributes.put(attribute.getName(),attribute); From 11cbe383207db04f696965e00bef0c8bf4ba93f6 Mon Sep 17 00:00:00 2001 From: Georgy Shabunin Date: Sun, 8 Dec 2013 22:45:07 +0100 Subject: [PATCH 18/37] "Grammar enlarged, interface changed" --- src/com/etk/network/client/Client.java | 2 +- .../etk/network/server/SessionHandler.java | 4 +- src/com/etk/parser/ProjectionCell.java | 18 + src/com/etk/parser/SELECT.g4 | 71 +- src/com/etk/parser/SELECT.tokens | 94 +- src/com/etk/parser/SELECTBaseListener.java | 242 +++- src/com/etk/parser/SELECTLexer.java | 129 +- src/com/etk/parser/SELECTLexer.tokens | 94 +- src/com/etk/parser/SELECTListener.java | 262 +++- src/com/etk/parser/SELECTParser.java | 1109 ++++++++++++++--- src/com/etk/parser/SelectObject.java | 28 +- src/com/etk/parser/SelectQueryToObject.java | 6 +- src/com/etk/parser/test.txt | 1 + 13 files changed, 1646 insertions(+), 414 deletions(-) create mode 100644 src/com/etk/parser/ProjectionCell.java create mode 100644 src/com/etk/parser/test.txt diff --git a/src/com/etk/network/client/Client.java b/src/com/etk/network/client/Client.java index 1fefbf4..d148588 100644 --- a/src/com/etk/network/client/Client.java +++ b/src/com/etk/network/client/Client.java @@ -79,7 +79,7 @@ private void query(Connection conn, ArrayList list, String query) { try { Statement st = conn.createStatement(); // the syntax for FROM is schema.table - ResultSet rs = st.executeQuery("SELECT id, name, surname FROM student"); + ResultSet rs = st.executeQuery("SELECT a FROM b, c INNER JOIN z USING (a, b, c)"); while (rs.next()) { String name = rs.getString("name"); System.out.println(name); diff --git a/src/com/etk/network/server/SessionHandler.java b/src/com/etk/network/server/SessionHandler.java index c3fdb7a..129a521 100644 --- a/src/com/etk/network/server/SessionHandler.java +++ b/src/com/etk/network/server/SessionHandler.java @@ -184,14 +184,14 @@ public void run() { SelectObject selectObject = selectQueryToObject.getSelectObject(); //just for understanding of how to use selectObject: - for(String columnName : selectObject.getColumnNames()){ +/* for(String columnName : selectObject.getNoPrefColNames()){ System.out.println("Column: " + columnName); } for(String tableName : selectObject.getTableNames()){ System.out.println("Table: " + tableName); } - +*/ /* * this is in case the server receive an empty query string and * seems to work sendEmptyQueryResponseMessage(dataOutputStream); diff --git a/src/com/etk/parser/ProjectionCell.java b/src/com/etk/parser/ProjectionCell.java new file mode 100644 index 0000000..da8291f --- /dev/null +++ b/src/com/etk/parser/ProjectionCell.java @@ -0,0 +1,18 @@ +package com.etk.parser; + +/** + * Created with IntelliJ IDEA. + * User: Georgy + * Date: 08.12.13 + * Time: 22:30 + * To change this template use File | Settings | File Templates. + */ +public class ProjectionCell { + private String prefix; + private String columnName; + + public ProjectionCell(String prefix, String columnName){ + this.prefix = prefix; + this.columnName = columnName; + } +} diff --git a/src/com/etk/parser/SELECT.g4 b/src/com/etk/parser/SELECT.g4 index a80475e..6c08c67 100644 --- a/src/com/etk/parser/SELECT.g4 +++ b/src/com/etk/parser/SELECT.g4 @@ -3,16 +3,22 @@ grammar SELECT; selectStmnt : 'SELECT' querySpecification ; querySpecification: - (setQuantifier)? selectList tableExpression ; + (setQuantifier)? selectList tableExpression (resultExpression)? ; setQuantifier : 'DISTINCT' | 'ALL' ; selectList: '*' - | derivedColumn (',' derivedColumn)* ; + | column (',' column)* ; -derivedColumn: +column: + columnInTable + | freeColumn; + +columnInTable: + tableName'.'columnName; +freeColumn: columnName (asClause)? ; asClause: @@ -64,16 +70,65 @@ truthValue : | 'UNKNOWN' ; booleanPrimary : - //predicate booleanPredicand ; -booleanPredicand : - parenthizedBooleanValueExpression - ; +booleanPredicand: + parenthesizedBoolValueExpr + ; -parenthizedBooleanValueExpression : +parenthesizedBoolValueExpr : '(' booleanValueExpression ')' ; +resultExpression: + joinClause; + +joinClause: + crossJoin + | qualifiedJoin + | naturalJoin + | unionJoin; + +crossJoin: + 'CROSS JOIN' tableName ; + +qualifiedJoin: + joinType 'JOIN' tableName joinSpec ; + +naturalJoin: + 'NATURAL' joinType 'JOIN' tableName ; + +unionJoin: + 'UNION JOIN' tableName ; + +joinType: + 'INNER' + | outerJoinType ('OUTER')? ; + +outerJoinType: + 'LEFT' + | 'RIGHT' + | 'FULL' ; + +joinSpec: + joinCondition + | namedColumnsJoin ; + +joinCondition: + 'ON' searchCondition ; + +namedColumnsJoin: + 'USING' '(' columnNameList ')' ; + +columnNameList: + columnName (',' columnName)* ; + + + + + + + + diff --git a/src/com/etk/parser/SELECT.tokens b/src/com/etk/parser/SELECT.tokens index ec5aabc..f130946 100644 --- a/src/com/etk/parser/SELECT.tokens +++ b/src/com/etk/parser/SELECT.tokens @@ -1,36 +1,60 @@ -WS=19 -T__16=1 -T__15=2 -T__12=5 -T__11=6 -T__14=3 -T__13=4 -T__1=16 -T__0=17 -T__3=14 -T__10=7 -T__2=15 -ID=18 -T__9=8 -T__8=9 -T__7=10 -T__6=11 -T__5=12 -T__4=13 -'FALSE'=17 -'SELECT'=16 -'NOT'=15 -'UNKNOWN'=14 -'TRUE'=13 -'FROM'=12 -'('=11 -'WHERE'=10 -'*'=9 -'OR'=8 -','=7 -')'=6 -'ALL'=5 -'IS'=4 -'AND'=3 +T__28=1 +T__27=2 +T__26=3 +T__25=4 +T__24=5 +T__23=6 +T__22=7 +T__21=8 +T__20=9 +ID=30 +T__9=20 +T__8=21 +T__7=22 +T__6=23 +T__5=24 +T__4=25 +T__19=10 +WS=31 +T__16=13 +T__15=14 +T__18=11 +T__17=12 +T__12=17 +T__11=18 +T__14=15 +T__13=16 +T__1=28 +T__0=29 +T__3=26 +T__10=19 +T__2=27 +'SELECT'=29 +'NOT'=28 +'FROM'=27 +'OUTER'=26 +'IS'=25 +'ON'=24 +'UNKNOWN'=23 +'LEFT'=22 +'.'=20 +')'=21 +'INNER'=18 +'NATURAL'=19 +'AND'=16 +'USING'=17 +'FALSE'=15 +'UNION JOIN'=14 +'JOIN'=13 +'TRUE'=12 +'OR'=11 +'FULL'=10 +'AS'=9 +'('=8 +'WHERE'=7 +'*'=6 +'RIGHT'=5 +','=4 +'ALL'=3 'DISTINCT'=2 -'AS'=1 +'CROSS JOIN'=1 diff --git a/src/com/etk/parser/SELECTBaseListener.java b/src/com/etk/parser/SELECTBaseListener.java index c9c53c3..123c0cd 100644 --- a/src/com/etk/parser/SELECTBaseListener.java +++ b/src/com/etk/parser/SELECTBaseListener.java @@ -29,26 +29,26 @@ public class SELECTBaseListener implements SELECTListener { *

* The default implementation does nothing. */ - @Override public void enterTableExpression(@NotNull SELECTParser.TableExpressionContext ctx) { } + @Override public void enterColumnNameList(@NotNull SELECTParser.ColumnNameListContext ctx) { } /** * {@inheritDoc} *

* The default implementation does nothing. */ - @Override public void exitTableExpression(@NotNull SELECTParser.TableExpressionContext ctx) { } + @Override public void exitColumnNameList(@NotNull SELECTParser.ColumnNameListContext ctx) { } /** * {@inheritDoc} *

* The default implementation does nothing. */ - @Override public void enterBooleanTest(@NotNull SELECTParser.BooleanTestContext ctx) { } + @Override public void enterTableExpression(@NotNull SELECTParser.TableExpressionContext ctx) { } /** * {@inheritDoc} *

* The default implementation does nothing. */ - @Override public void exitBooleanTest(@NotNull SELECTParser.BooleanTestContext ctx) { } + @Override public void exitTableExpression(@NotNull SELECTParser.TableExpressionContext ctx) { } /** * {@inheritDoc} @@ -68,26 +68,26 @@ public class SELECTBaseListener implements SELECTListener { *

* The default implementation does nothing. */ - @Override public void enterTablePrimary(@NotNull SELECTParser.TablePrimaryContext ctx) { } + @Override public void enterNamedColumnsJoin(@NotNull SELECTParser.NamedColumnsJoinContext ctx) { } /** * {@inheritDoc} *

* The default implementation does nothing. */ - @Override public void exitTablePrimary(@NotNull SELECTParser.TablePrimaryContext ctx) { } + @Override public void exitNamedColumnsJoin(@NotNull SELECTParser.NamedColumnsJoinContext ctx) { } /** * {@inheritDoc} *

* The default implementation does nothing. */ - @Override public void enterQuerySpecification(@NotNull SELECTParser.QuerySpecificationContext ctx) { } + @Override public void enterJoinCondition(@NotNull SELECTParser.JoinConditionContext ctx) { } /** * {@inheritDoc} *

* The default implementation does nothing. */ - @Override public void exitQuerySpecification(@NotNull SELECTParser.QuerySpecificationContext ctx) { } + @Override public void exitJoinCondition(@NotNull SELECTParser.JoinConditionContext ctx) { } /** * {@inheritDoc} @@ -107,26 +107,26 @@ public class SELECTBaseListener implements SELECTListener { *

* The default implementation does nothing. */ - @Override public void enterBooleanValueExpression(@NotNull SELECTParser.BooleanValueExpressionContext ctx) { } + @Override public void enterQuerySpecification(@NotNull SELECTParser.QuerySpecificationContext ctx) { } /** * {@inheritDoc} *

* The default implementation does nothing. */ - @Override public void exitBooleanValueExpression(@NotNull SELECTParser.BooleanValueExpressionContext ctx) { } + @Override public void exitQuerySpecification(@NotNull SELECTParser.QuerySpecificationContext ctx) { } /** * {@inheritDoc} *

* The default implementation does nothing. */ - @Override public void enterDerivedColumn(@NotNull SELECTParser.DerivedColumnContext ctx) { } + @Override public void enterBooleanTerm(@NotNull SELECTParser.BooleanTermContext ctx) { } /** * {@inheritDoc} *

* The default implementation does nothing. */ - @Override public void exitDerivedColumn(@NotNull SELECTParser.DerivedColumnContext ctx) { } + @Override public void exitBooleanTerm(@NotNull SELECTParser.BooleanTermContext ctx) { } /** * {@inheritDoc} @@ -146,13 +146,13 @@ public class SELECTBaseListener implements SELECTListener { *

* The default implementation does nothing. */ - @Override public void enterBooleanTerm(@NotNull SELECTParser.BooleanTermContext ctx) { } + @Override public void enterUnionJoin(@NotNull SELECTParser.UnionJoinContext ctx) { } /** * {@inheritDoc} *

* The default implementation does nothing. */ - @Override public void exitBooleanTerm(@NotNull SELECTParser.BooleanTermContext ctx) { } + @Override public void exitUnionJoin(@NotNull SELECTParser.UnionJoinContext ctx) { } /** * {@inheritDoc} @@ -172,91 +172,260 @@ public class SELECTBaseListener implements SELECTListener { *

* The default implementation does nothing. */ - @Override public void enterTablePrimaryAs(@NotNull SELECTParser.TablePrimaryAsContext ctx) { } + @Override public void enterDerivedColumnList(@NotNull SELECTParser.DerivedColumnListContext ctx) { } /** * {@inheritDoc} *

* The default implementation does nothing. */ - @Override public void exitTablePrimaryAs(@NotNull SELECTParser.TablePrimaryAsContext ctx) { } + @Override public void exitDerivedColumnList(@NotNull SELECTParser.DerivedColumnListContext ctx) { } /** * {@inheritDoc} *

* The default implementation does nothing. */ - @Override public void enterDerivedColumnList(@NotNull SELECTParser.DerivedColumnListContext ctx) { } + @Override public void enterSetQuantifier(@NotNull SELECTParser.SetQuantifierContext ctx) { } /** * {@inheritDoc} *

* The default implementation does nothing. */ - @Override public void exitDerivedColumnList(@NotNull SELECTParser.DerivedColumnListContext ctx) { } + @Override public void exitSetQuantifier(@NotNull SELECTParser.SetQuantifierContext ctx) { } /** * {@inheritDoc} *

* The default implementation does nothing. */ - @Override public void enterSetQuantifier(@NotNull SELECTParser.SetQuantifierContext ctx) { } + @Override public void enterTableName(@NotNull SELECTParser.TableNameContext ctx) { } /** * {@inheritDoc} *

* The default implementation does nothing. */ - @Override public void exitSetQuantifier(@NotNull SELECTParser.SetQuantifierContext ctx) { } + @Override public void exitTableName(@NotNull SELECTParser.TableNameContext ctx) { } /** * {@inheritDoc} *

* The default implementation does nothing. */ - @Override public void enterTableName(@NotNull SELECTParser.TableNameContext ctx) { } + @Override public void enterSearchCondition(@NotNull SELECTParser.SearchConditionContext ctx) { } /** * {@inheritDoc} *

* The default implementation does nothing. */ - @Override public void exitTableName(@NotNull SELECTParser.TableNameContext ctx) { } + @Override public void exitSearchCondition(@NotNull SELECTParser.SearchConditionContext ctx) { } /** * {@inheritDoc} *

* The default implementation does nothing. */ - @Override public void enterParenthizedBooleanValueExpression(@NotNull SELECTParser.ParenthizedBooleanValueExpressionContext ctx) { } + @Override public void enterColumnName(@NotNull SELECTParser.ColumnNameContext ctx) { } /** * {@inheritDoc} *

* The default implementation does nothing. */ - @Override public void exitParenthizedBooleanValueExpression(@NotNull SELECTParser.ParenthizedBooleanValueExpressionContext ctx) { } + @Override public void exitColumnName(@NotNull SELECTParser.ColumnNameContext ctx) { } /** * {@inheritDoc} *

* The default implementation does nothing. */ - @Override public void enterSearchCondition(@NotNull SELECTParser.SearchConditionContext ctx) { } + @Override public void enterCrossJoin(@NotNull SELECTParser.CrossJoinContext ctx) { } /** * {@inheritDoc} *

* The default implementation does nothing. */ - @Override public void exitSearchCondition(@NotNull SELECTParser.SearchConditionContext ctx) { } + @Override public void exitCrossJoin(@NotNull SELECTParser.CrossJoinContext ctx) { } /** * {@inheritDoc} *

* The default implementation does nothing. */ - @Override public void enterColumnName(@NotNull SELECTParser.ColumnNameContext ctx) { } + @Override public void enterSelectStmnt(@NotNull SELECTParser.SelectStmntContext ctx) { } /** * {@inheritDoc} *

* The default implementation does nothing. */ - @Override public void exitColumnName(@NotNull SELECTParser.ColumnNameContext ctx) { } + @Override public void exitSelectStmnt(@NotNull SELECTParser.SelectStmntContext ctx) { } + + /** + * {@inheritDoc} + *

+ * The default implementation does nothing. + */ + @Override public void enterColumnInTable(@NotNull SELECTParser.ColumnInTableContext ctx) { } + /** + * {@inheritDoc} + *

+ * The default implementation does nothing. + */ + @Override public void exitColumnInTable(@NotNull SELECTParser.ColumnInTableContext ctx) { } + + /** + * {@inheritDoc} + *

+ * The default implementation does nothing. + */ + @Override public void enterJoinSpec(@NotNull SELECTParser.JoinSpecContext ctx) { } + /** + * {@inheritDoc} + *

+ * The default implementation does nothing. + */ + @Override public void exitJoinSpec(@NotNull SELECTParser.JoinSpecContext ctx) { } + + /** + * {@inheritDoc} + *

+ * The default implementation does nothing. + */ + @Override public void enterBooleanTest(@NotNull SELECTParser.BooleanTestContext ctx) { } + /** + * {@inheritDoc} + *

+ * The default implementation does nothing. + */ + @Override public void exitBooleanTest(@NotNull SELECTParser.BooleanTestContext ctx) { } + + /** + * {@inheritDoc} + *

+ * The default implementation does nothing. + */ + @Override public void enterParenthesizedBoolValueExpr(@NotNull SELECTParser.ParenthesizedBoolValueExprContext ctx) { } + /** + * {@inheritDoc} + *

+ * The default implementation does nothing. + */ + @Override public void exitParenthesizedBoolValueExpr(@NotNull SELECTParser.ParenthesizedBoolValueExprContext ctx) { } + + /** + * {@inheritDoc} + *

+ * The default implementation does nothing. + */ + @Override public void enterTablePrimary(@NotNull SELECTParser.TablePrimaryContext ctx) { } + /** + * {@inheritDoc} + *

+ * The default implementation does nothing. + */ + @Override public void exitTablePrimary(@NotNull SELECTParser.TablePrimaryContext ctx) { } + + /** + * {@inheritDoc} + *

+ * The default implementation does nothing. + */ + @Override public void enterFreeColumn(@NotNull SELECTParser.FreeColumnContext ctx) { } + /** + * {@inheritDoc} + *

+ * The default implementation does nothing. + */ + @Override public void exitFreeColumn(@NotNull SELECTParser.FreeColumnContext ctx) { } + + /** + * {@inheritDoc} + *

+ * The default implementation does nothing. + */ + @Override public void enterBooleanValueExpression(@NotNull SELECTParser.BooleanValueExpressionContext ctx) { } + /** + * {@inheritDoc} + *

+ * The default implementation does nothing. + */ + @Override public void exitBooleanValueExpression(@NotNull SELECTParser.BooleanValueExpressionContext ctx) { } + + /** + * {@inheritDoc} + *

+ * The default implementation does nothing. + */ + @Override public void enterJoinClause(@NotNull SELECTParser.JoinClauseContext ctx) { } + /** + * {@inheritDoc} + *

+ * The default implementation does nothing. + */ + @Override public void exitJoinClause(@NotNull SELECTParser.JoinClauseContext ctx) { } + + /** + * {@inheritDoc} + *

+ * The default implementation does nothing. + */ + @Override public void enterResultExpression(@NotNull SELECTParser.ResultExpressionContext ctx) { } + /** + * {@inheritDoc} + *

+ * The default implementation does nothing. + */ + @Override public void exitResultExpression(@NotNull SELECTParser.ResultExpressionContext ctx) { } + + /** + * {@inheritDoc} + *

+ * The default implementation does nothing. + */ + @Override public void enterTablePrimaryAs(@NotNull SELECTParser.TablePrimaryAsContext ctx) { } + /** + * {@inheritDoc} + *

+ * The default implementation does nothing. + */ + @Override public void exitTablePrimaryAs(@NotNull SELECTParser.TablePrimaryAsContext ctx) { } + + /** + * {@inheritDoc} + *

+ * The default implementation does nothing. + */ + @Override public void enterNaturalJoin(@NotNull SELECTParser.NaturalJoinContext ctx) { } + /** + * {@inheritDoc} + *

+ * The default implementation does nothing. + */ + @Override public void exitNaturalJoin(@NotNull SELECTParser.NaturalJoinContext ctx) { } + + /** + * {@inheritDoc} + *

+ * The default implementation does nothing. + */ + @Override public void enterColumn(@NotNull SELECTParser.ColumnContext ctx) { } + /** + * {@inheritDoc} + *

+ * The default implementation does nothing. + */ + @Override public void exitColumn(@NotNull SELECTParser.ColumnContext ctx) { } + + /** + * {@inheritDoc} + *

+ * The default implementation does nothing. + */ + @Override public void enterQualifiedJoin(@NotNull SELECTParser.QualifiedJoinContext ctx) { } + /** + * {@inheritDoc} + *

+ * The default implementation does nothing. + */ + @Override public void exitQualifiedJoin(@NotNull SELECTParser.QualifiedJoinContext ctx) { } /** * {@inheritDoc} @@ -289,13 +458,26 @@ public class SELECTBaseListener implements SELECTListener { *

* The default implementation does nothing. */ - @Override public void enterSelectStmnt(@NotNull SELECTParser.SelectStmntContext ctx) { } + @Override public void enterJoinType(@NotNull SELECTParser.JoinTypeContext ctx) { } /** * {@inheritDoc} *

* The default implementation does nothing. */ - @Override public void exitSelectStmnt(@NotNull SELECTParser.SelectStmntContext ctx) { } + @Override public void exitJoinType(@NotNull SELECTParser.JoinTypeContext ctx) { } + + /** + * {@inheritDoc} + *

+ * The default implementation does nothing. + */ + @Override public void enterOuterJoinType(@NotNull SELECTParser.OuterJoinTypeContext ctx) { } + /** + * {@inheritDoc} + *

+ * The default implementation does nothing. + */ + @Override public void exitOuterJoinType(@NotNull SELECTParser.OuterJoinTypeContext ctx) { } /** * {@inheritDoc} diff --git a/src/com/etk/parser/SELECTLexer.java b/src/com/etk/parser/SELECTLexer.java index 85bd936..0bcea33 100644 --- a/src/com/etk/parser/SELECTLexer.java +++ b/src/com/etk/parser/SELECTLexer.java @@ -15,23 +15,26 @@ public class SELECTLexer extends Lexer { protected static final PredictionContextCache _sharedContextCache = new PredictionContextCache(); public static final int - T__16=1, T__15=2, T__14=3, T__13=4, T__12=5, T__11=6, T__10=7, T__9=8, - T__8=9, T__7=10, T__6=11, T__5=12, T__4=13, T__3=14, T__2=15, T__1=16, - T__0=17, ID=18, WS=19; + T__28=1, T__27=2, T__26=3, T__25=4, T__24=5, T__23=6, T__22=7, T__21=8, + T__20=9, T__19=10, T__18=11, T__17=12, T__16=13, T__15=14, T__14=15, T__13=16, + T__12=17, T__11=18, T__10=19, T__9=20, T__8=21, T__7=22, T__6=23, T__5=24, + T__4=25, T__3=26, T__2=27, T__1=28, T__0=29, ID=30, WS=31; public static String[] modeNames = { "DEFAULT_MODE" }; public static final String[] tokenNames = { "", - "'AS'", "'DISTINCT'", "'AND'", "'IS'", "'ALL'", "')'", "','", "'OR'", - "'*'", "'WHERE'", "'('", "'FROM'", "'TRUE'", "'UNKNOWN'", "'NOT'", "'SELECT'", - "'FALSE'", "ID", "WS" + "'CROSS JOIN'", "'DISTINCT'", "'ALL'", "','", "'RIGHT'", "'*'", "'WHERE'", + "'('", "'AS'", "'FULL'", "'OR'", "'TRUE'", "'JOIN'", "'UNION JOIN'", "'FALSE'", + "'AND'", "'USING'", "'INNER'", "'NATURAL'", "'.'", "')'", "'LEFT'", "'UNKNOWN'", + "'ON'", "'IS'", "'OUTER'", "'FROM'", "'NOT'", "'SELECT'", "ID", "WS" }; public static final String[] ruleNames = { - "T__16", "T__15", "T__14", "T__13", "T__12", "T__11", "T__10", "T__9", - "T__8", "T__7", "T__6", "T__5", "T__4", "T__3", "T__2", "T__1", "T__0", - "ID", "ID_LETTER", "DIGIT", "WS" + "T__28", "T__27", "T__26", "T__25", "T__24", "T__23", "T__22", "T__21", + "T__20", "T__19", "T__18", "T__17", "T__16", "T__15", "T__14", "T__13", + "T__12", "T__11", "T__10", "T__9", "T__8", "T__7", "T__6", "T__5", "T__4", + "T__3", "T__2", "T__1", "T__0", "ID", "ID_LETTER", "DIGIT", "WS" }; @@ -58,7 +61,7 @@ public SELECTLexer(CharStream input) { @Override public void action(RuleContext _localctx, int ruleIndex, int actionIndex) { switch (ruleIndex) { - case 20: WS_action((RuleContext)_localctx, actionIndex); break; + case 32: WS_action((RuleContext)_localctx, actionIndex); break; } } private void WS_action(RuleContext _localctx, int actionIndex) { @@ -68,42 +71,76 @@ private void WS_action(RuleContext _localctx, int actionIndex) { } public static final String _serializedATN = - "\3\uacf5\uee8c\u4f5d\u8b0d\u4a45\u78bd\u1b2f\u3378\2\25\u008b\b\1\4\2"+ - "\t\2\4\3\t\3\4\4\t\4\4\5\t\5\4\6\t\6\4\7\t\7\4\b\t\b\4\t\t\t\4\n\t\n\4"+ - "\13\t\13\4\f\t\f\4\r\t\r\4\16\t\16\4\17\t\17\4\20\t\20\4\21\t\21\4\22"+ - "\t\22\4\23\t\23\4\24\t\24\4\25\t\25\4\26\t\26\3\2\3\2\3\2\3\3\3\3\3\3"+ - "\3\3\3\3\3\3\3\3\3\3\3\3\3\4\3\4\3\4\3\4\3\5\3\5\3\5\3\6\3\6\3\6\3\6\3"+ - "\7\3\7\3\b\3\b\3\t\3\t\3\t\3\n\3\n\3\13\3\13\3\13\3\13\3\13\3\13\3\f\3"+ - "\f\3\r\3\r\3\r\3\r\3\r\3\16\3\16\3\16\3\16\3\16\3\17\3\17\3\17\3\17\3"+ - "\17\3\17\3\17\3\17\3\20\3\20\3\20\3\20\3\21\3\21\3\21\3\21\3\21\3\21\3"+ - "\21\3\22\3\22\3\22\3\22\3\22\3\22\3\23\3\23\3\23\7\23|\n\23\f\23\16\23"+ - "\177\13\23\3\24\3\24\3\25\3\25\3\26\6\26\u0086\n\26\r\26\16\26\u0087\3"+ - "\26\3\26\2\27\3\3\1\5\4\1\7\5\1\t\6\1\13\7\1\r\b\1\17\t\1\21\n\1\23\13"+ - "\1\25\f\1\27\r\1\31\16\1\33\17\1\35\20\1\37\21\1!\22\1#\23\1%\24\1\'\2"+ - "\1)\2\1+\25\2\3\2\4\5\2C\\aac|\5\2\13\f\17\17\"\"\u008b\2\3\3\2\2\2\2"+ - "\5\3\2\2\2\2\7\3\2\2\2\2\t\3\2\2\2\2\13\3\2\2\2\2\r\3\2\2\2\2\17\3\2\2"+ - "\2\2\21\3\2\2\2\2\23\3\2\2\2\2\25\3\2\2\2\2\27\3\2\2\2\2\31\3\2\2\2\2"+ - "\33\3\2\2\2\2\35\3\2\2\2\2\37\3\2\2\2\2!\3\2\2\2\2#\3\2\2\2\2%\3\2\2\2"+ - "\2+\3\2\2\2\3-\3\2\2\2\5\60\3\2\2\2\79\3\2\2\2\t=\3\2\2\2\13@\3\2\2\2"+ - "\rD\3\2\2\2\17F\3\2\2\2\21H\3\2\2\2\23K\3\2\2\2\25M\3\2\2\2\27S\3\2\2"+ - "\2\31U\3\2\2\2\33Z\3\2\2\2\35_\3\2\2\2\37g\3\2\2\2!k\3\2\2\2#r\3\2\2\2"+ - "%x\3\2\2\2\'\u0080\3\2\2\2)\u0082\3\2\2\2+\u0085\3\2\2\2-.\7C\2\2./\7"+ - "U\2\2/\4\3\2\2\2\60\61\7F\2\2\61\62\7K\2\2\62\63\7U\2\2\63\64\7V\2\2\64"+ - "\65\7K\2\2\65\66\7P\2\2\66\67\7E\2\2\678\7V\2\28\6\3\2\2\29:\7C\2\2:;"+ - "\7P\2\2;<\7F\2\2<\b\3\2\2\2=>\7K\2\2>?\7U\2\2?\n\3\2\2\2@A\7C\2\2AB\7"+ - "N\2\2BC\7N\2\2C\f\3\2\2\2DE\7+\2\2E\16\3\2\2\2FG\7.\2\2G\20\3\2\2\2HI"+ - "\7Q\2\2IJ\7T\2\2J\22\3\2\2\2KL\7,\2\2L\24\3\2\2\2MN\7Y\2\2NO\7J\2\2OP"+ - "\7G\2\2PQ\7T\2\2QR\7G\2\2R\26\3\2\2\2ST\7*\2\2T\30\3\2\2\2UV\7H\2\2VW"+ - "\7T\2\2WX\7Q\2\2XY\7O\2\2Y\32\3\2\2\2Z[\7V\2\2[\\\7T\2\2\\]\7W\2\2]^\7"+ - "G\2\2^\34\3\2\2\2_`\7W\2\2`a\7P\2\2ab\7M\2\2bc\7P\2\2cd\7Q\2\2de\7Y\2"+ - "\2ef\7P\2\2f\36\3\2\2\2gh\7P\2\2hi\7Q\2\2ij\7V\2\2j \3\2\2\2kl\7U\2\2"+ - "lm\7G\2\2mn\7N\2\2no\7G\2\2op\7E\2\2pq\7V\2\2q\"\3\2\2\2rs\7H\2\2st\7"+ - "C\2\2tu\7N\2\2uv\7U\2\2vw\7G\2\2w$\3\2\2\2x}\5\'\24\2y|\5\'\24\2z|\5)"+ - "\25\2{y\3\2\2\2{z\3\2\2\2|\177\3\2\2\2}{\3\2\2\2}~\3\2\2\2~&\3\2\2\2\177"+ - "}\3\2\2\2\u0080\u0081\t\2\2\2\u0081(\3\2\2\2\u0082\u0083\4\62;\2\u0083"+ - "*\3\2\2\2\u0084\u0086\t\3\2\2\u0085\u0084\3\2\2\2\u0086\u0087\3\2\2\2"+ - "\u0087\u0085\3\2\2\2\u0087\u0088\3\2\2\2\u0088\u0089\3\2\2\2\u0089\u008a"+ - "\b\26\2\2\u008a,\3\2\2\2\6\2{}\u0087"; + "\3\uacf5\uee8c\u4f5d\u8b0d\u4a45\u78bd\u1b2f\u3378\2!\u00ed\b\1\4\2\t"+ + "\2\4\3\t\3\4\4\t\4\4\5\t\5\4\6\t\6\4\7\t\7\4\b\t\b\4\t\t\t\4\n\t\n\4\13"+ + "\t\13\4\f\t\f\4\r\t\r\4\16\t\16\4\17\t\17\4\20\t\20\4\21\t\21\4\22\t\22"+ + "\4\23\t\23\4\24\t\24\4\25\t\25\4\26\t\26\4\27\t\27\4\30\t\30\4\31\t\31"+ + "\4\32\t\32\4\33\t\33\4\34\t\34\4\35\t\35\4\36\t\36\4\37\t\37\4 \t \4!"+ + "\t!\4\"\t\"\3\2\3\2\3\2\3\2\3\2\3\2\3\2\3\2\3\2\3\2\3\2\3\3\3\3\3\3\3"+ + "\3\3\3\3\3\3\3\3\3\3\3\3\4\3\4\3\4\3\4\3\5\3\5\3\6\3\6\3\6\3\6\3\6\3\6"+ + "\3\7\3\7\3\b\3\b\3\b\3\b\3\b\3\b\3\t\3\t\3\n\3\n\3\n\3\13\3\13\3\13\3"+ + "\13\3\13\3\f\3\f\3\f\3\r\3\r\3\r\3\r\3\r\3\16\3\16\3\16\3\16\3\16\3\17"+ + "\3\17\3\17\3\17\3\17\3\17\3\17\3\17\3\17\3\17\3\17\3\20\3\20\3\20\3\20"+ + "\3\20\3\20\3\21\3\21\3\21\3\21\3\22\3\22\3\22\3\22\3\22\3\22\3\23\3\23"+ + "\3\23\3\23\3\23\3\23\3\24\3\24\3\24\3\24\3\24\3\24\3\24\3\24\3\25\3\25"+ + "\3\26\3\26\3\27\3\27\3\27\3\27\3\27\3\30\3\30\3\30\3\30\3\30\3\30\3\30"+ + "\3\30\3\31\3\31\3\31\3\32\3\32\3\32\3\33\3\33\3\33\3\33\3\33\3\33\3\34"+ + "\3\34\3\34\3\34\3\34\3\35\3\35\3\35\3\35\3\36\3\36\3\36\3\36\3\36\3\36"+ + "\3\36\3\37\3\37\3\37\7\37\u00de\n\37\f\37\16\37\u00e1\13\37\3 \3 \3!\3"+ + "!\3\"\6\"\u00e8\n\"\r\"\16\"\u00e9\3\"\3\"\2#\3\3\1\5\4\1\7\5\1\t\6\1"+ + "\13\7\1\r\b\1\17\t\1\21\n\1\23\13\1\25\f\1\27\r\1\31\16\1\33\17\1\35\20"+ + "\1\37\21\1!\22\1#\23\1%\24\1\'\25\1)\26\1+\27\1-\30\1/\31\1\61\32\1\63"+ + "\33\1\65\34\1\67\35\19\36\1;\37\1= \1?\2\1A\2\1C!\2\3\2\4\5\2C\\aac|\5"+ + "\2\13\f\17\17\"\"\u00ed\2\3\3\2\2\2\2\5\3\2\2\2\2\7\3\2\2\2\2\t\3\2\2"+ + "\2\2\13\3\2\2\2\2\r\3\2\2\2\2\17\3\2\2\2\2\21\3\2\2\2\2\23\3\2\2\2\2\25"+ + "\3\2\2\2\2\27\3\2\2\2\2\31\3\2\2\2\2\33\3\2\2\2\2\35\3\2\2\2\2\37\3\2"+ + "\2\2\2!\3\2\2\2\2#\3\2\2\2\2%\3\2\2\2\2\'\3\2\2\2\2)\3\2\2\2\2+\3\2\2"+ + "\2\2-\3\2\2\2\2/\3\2\2\2\2\61\3\2\2\2\2\63\3\2\2\2\2\65\3\2\2\2\2\67\3"+ + "\2\2\2\29\3\2\2\2\2;\3\2\2\2\2=\3\2\2\2\2C\3\2\2\2\3E\3\2\2\2\5P\3\2\2"+ + "\2\7Y\3\2\2\2\t]\3\2\2\2\13_\3\2\2\2\re\3\2\2\2\17g\3\2\2\2\21m\3\2\2"+ + "\2\23o\3\2\2\2\25r\3\2\2\2\27w\3\2\2\2\31z\3\2\2\2\33\177\3\2\2\2\35\u0084"+ + "\3\2\2\2\37\u008f\3\2\2\2!\u0095\3\2\2\2#\u0099\3\2\2\2%\u009f\3\2\2\2"+ + "\'\u00a5\3\2\2\2)\u00ad\3\2\2\2+\u00af\3\2\2\2-\u00b1\3\2\2\2/\u00b6\3"+ + "\2\2\2\61\u00be\3\2\2\2\63\u00c1\3\2\2\2\65\u00c4\3\2\2\2\67\u00ca\3\2"+ + "\2\29\u00cf\3\2\2\2;\u00d3\3\2\2\2=\u00da\3\2\2\2?\u00e2\3\2\2\2A\u00e4"+ + "\3\2\2\2C\u00e7\3\2\2\2EF\7E\2\2FG\7T\2\2GH\7Q\2\2HI\7U\2\2IJ\7U\2\2J"+ + "K\7\"\2\2KL\7L\2\2LM\7Q\2\2MN\7K\2\2NO\7P\2\2O\4\3\2\2\2PQ\7F\2\2QR\7"+ + "K\2\2RS\7U\2\2ST\7V\2\2TU\7K\2\2UV\7P\2\2VW\7E\2\2WX\7V\2\2X\6\3\2\2\2"+ + "YZ\7C\2\2Z[\7N\2\2[\\\7N\2\2\\\b\3\2\2\2]^\7.\2\2^\n\3\2\2\2_`\7T\2\2"+ + "`a\7K\2\2ab\7I\2\2bc\7J\2\2cd\7V\2\2d\f\3\2\2\2ef\7,\2\2f\16\3\2\2\2g"+ + "h\7Y\2\2hi\7J\2\2ij\7G\2\2jk\7T\2\2kl\7G\2\2l\20\3\2\2\2mn\7*\2\2n\22"+ + "\3\2\2\2op\7C\2\2pq\7U\2\2q\24\3\2\2\2rs\7H\2\2st\7W\2\2tu\7N\2\2uv\7"+ + "N\2\2v\26\3\2\2\2wx\7Q\2\2xy\7T\2\2y\30\3\2\2\2z{\7V\2\2{|\7T\2\2|}\7"+ + "W\2\2}~\7G\2\2~\32\3\2\2\2\177\u0080\7L\2\2\u0080\u0081\7Q\2\2\u0081\u0082"+ + "\7K\2\2\u0082\u0083\7P\2\2\u0083\34\3\2\2\2\u0084\u0085\7W\2\2\u0085\u0086"+ + "\7P\2\2\u0086\u0087\7K\2\2\u0087\u0088\7Q\2\2\u0088\u0089\7P\2\2\u0089"+ + "\u008a\7\"\2\2\u008a\u008b\7L\2\2\u008b\u008c\7Q\2\2\u008c\u008d\7K\2"+ + "\2\u008d\u008e\7P\2\2\u008e\36\3\2\2\2\u008f\u0090\7H\2\2\u0090\u0091"+ + "\7C\2\2\u0091\u0092\7N\2\2\u0092\u0093\7U\2\2\u0093\u0094\7G\2\2\u0094"+ + " \3\2\2\2\u0095\u0096\7C\2\2\u0096\u0097\7P\2\2\u0097\u0098\7F\2\2\u0098"+ + "\"\3\2\2\2\u0099\u009a\7W\2\2\u009a\u009b\7U\2\2\u009b\u009c\7K\2\2\u009c"+ + "\u009d\7P\2\2\u009d\u009e\7I\2\2\u009e$\3\2\2\2\u009f\u00a0\7K\2\2\u00a0"+ + "\u00a1\7P\2\2\u00a1\u00a2\7P\2\2\u00a2\u00a3\7G\2\2\u00a3\u00a4\7T\2\2"+ + "\u00a4&\3\2\2\2\u00a5\u00a6\7P\2\2\u00a6\u00a7\7C\2\2\u00a7\u00a8\7V\2"+ + "\2\u00a8\u00a9\7W\2\2\u00a9\u00aa\7T\2\2\u00aa\u00ab\7C\2\2\u00ab\u00ac"+ + "\7N\2\2\u00ac(\3\2\2\2\u00ad\u00ae\7\60\2\2\u00ae*\3\2\2\2\u00af\u00b0"+ + "\7+\2\2\u00b0,\3\2\2\2\u00b1\u00b2\7N\2\2\u00b2\u00b3\7G\2\2\u00b3\u00b4"+ + "\7H\2\2\u00b4\u00b5\7V\2\2\u00b5.\3\2\2\2\u00b6\u00b7\7W\2\2\u00b7\u00b8"+ + "\7P\2\2\u00b8\u00b9\7M\2\2\u00b9\u00ba\7P\2\2\u00ba\u00bb\7Q\2\2\u00bb"+ + "\u00bc\7Y\2\2\u00bc\u00bd\7P\2\2\u00bd\60\3\2\2\2\u00be\u00bf\7Q\2\2\u00bf"+ + "\u00c0\7P\2\2\u00c0\62\3\2\2\2\u00c1\u00c2\7K\2\2\u00c2\u00c3\7U\2\2\u00c3"+ + "\64\3\2\2\2\u00c4\u00c5\7Q\2\2\u00c5\u00c6\7W\2\2\u00c6\u00c7\7V\2\2\u00c7"+ + "\u00c8\7G\2\2\u00c8\u00c9\7T\2\2\u00c9\66\3\2\2\2\u00ca\u00cb\7H\2\2\u00cb"+ + "\u00cc\7T\2\2\u00cc\u00cd\7Q\2\2\u00cd\u00ce\7O\2\2\u00ce8\3\2\2\2\u00cf"+ + "\u00d0\7P\2\2\u00d0\u00d1\7Q\2\2\u00d1\u00d2\7V\2\2\u00d2:\3\2\2\2\u00d3"+ + "\u00d4\7U\2\2\u00d4\u00d5\7G\2\2\u00d5\u00d6\7N\2\2\u00d6\u00d7\7G\2\2"+ + "\u00d7\u00d8\7E\2\2\u00d8\u00d9\7V\2\2\u00d9<\3\2\2\2\u00da\u00df\5? "+ + "\2\u00db\u00de\5? \2\u00dc\u00de\5A!\2\u00dd\u00db\3\2\2\2\u00dd\u00dc"+ + "\3\2\2\2\u00de\u00e1\3\2\2\2\u00df\u00dd\3\2\2\2\u00df\u00e0\3\2\2\2\u00e0"+ + ">\3\2\2\2\u00e1\u00df\3\2\2\2\u00e2\u00e3\t\2\2\2\u00e3@\3\2\2\2\u00e4"+ + "\u00e5\4\62;\2\u00e5B\3\2\2\2\u00e6\u00e8\t\3\2\2\u00e7\u00e6\3\2\2\2"+ + "\u00e8\u00e9\3\2\2\2\u00e9\u00e7\3\2\2\2\u00e9\u00ea\3\2\2\2\u00ea\u00eb"+ + "\3\2\2\2\u00eb\u00ec\b\"\2\2\u00ecD\3\2\2\2\6\2\u00dd\u00df\u00e9"; public static final ATN _ATN = ATNSimulator.deserialize(_serializedATN.toCharArray()); static { diff --git a/src/com/etk/parser/SELECTLexer.tokens b/src/com/etk/parser/SELECTLexer.tokens index ec5aabc..f130946 100644 --- a/src/com/etk/parser/SELECTLexer.tokens +++ b/src/com/etk/parser/SELECTLexer.tokens @@ -1,36 +1,60 @@ -WS=19 -T__16=1 -T__15=2 -T__12=5 -T__11=6 -T__14=3 -T__13=4 -T__1=16 -T__0=17 -T__3=14 -T__10=7 -T__2=15 -ID=18 -T__9=8 -T__8=9 -T__7=10 -T__6=11 -T__5=12 -T__4=13 -'FALSE'=17 -'SELECT'=16 -'NOT'=15 -'UNKNOWN'=14 -'TRUE'=13 -'FROM'=12 -'('=11 -'WHERE'=10 -'*'=9 -'OR'=8 -','=7 -')'=6 -'ALL'=5 -'IS'=4 -'AND'=3 +T__28=1 +T__27=2 +T__26=3 +T__25=4 +T__24=5 +T__23=6 +T__22=7 +T__21=8 +T__20=9 +ID=30 +T__9=20 +T__8=21 +T__7=22 +T__6=23 +T__5=24 +T__4=25 +T__19=10 +WS=31 +T__16=13 +T__15=14 +T__18=11 +T__17=12 +T__12=17 +T__11=18 +T__14=15 +T__13=16 +T__1=28 +T__0=29 +T__3=26 +T__10=19 +T__2=27 +'SELECT'=29 +'NOT'=28 +'FROM'=27 +'OUTER'=26 +'IS'=25 +'ON'=24 +'UNKNOWN'=23 +'LEFT'=22 +'.'=20 +')'=21 +'INNER'=18 +'NATURAL'=19 +'AND'=16 +'USING'=17 +'FALSE'=15 +'UNION JOIN'=14 +'JOIN'=13 +'TRUE'=12 +'OR'=11 +'FULL'=10 +'AS'=9 +'('=8 +'WHERE'=7 +'*'=6 +'RIGHT'=5 +','=4 +'ALL'=3 'DISTINCT'=2 -'AS'=1 +'CROSS JOIN'=1 diff --git a/src/com/etk/parser/SELECTListener.java b/src/com/etk/parser/SELECTListener.java index b75cbce..a277a6a 100644 --- a/src/com/etk/parser/SELECTListener.java +++ b/src/com/etk/parser/SELECTListener.java @@ -19,26 +19,26 @@ public interface SELECTListener extends ParseTreeListener { void exitWhereClause(@NotNull SELECTParser.WhereClauseContext ctx); /** - * Enter a parse tree produced by {@link SELECTParser#tableExpression}. + * Enter a parse tree produced by {@link SELECTParser#columnNameList}. * @param ctx the parse tree */ - void enterTableExpression(@NotNull SELECTParser.TableExpressionContext ctx); + void enterColumnNameList(@NotNull SELECTParser.ColumnNameListContext ctx); /** - * Exit a parse tree produced by {@link SELECTParser#tableExpression}. + * Exit a parse tree produced by {@link SELECTParser#columnNameList}. * @param ctx the parse tree */ - void exitTableExpression(@NotNull SELECTParser.TableExpressionContext ctx); + void exitColumnNameList(@NotNull SELECTParser.ColumnNameListContext ctx); /** - * Enter a parse tree produced by {@link SELECTParser#booleanTest}. + * Enter a parse tree produced by {@link SELECTParser#tableExpression}. * @param ctx the parse tree */ - void enterBooleanTest(@NotNull SELECTParser.BooleanTestContext ctx); + void enterTableExpression(@NotNull SELECTParser.TableExpressionContext ctx); /** - * Exit a parse tree produced by {@link SELECTParser#booleanTest}. + * Exit a parse tree produced by {@link SELECTParser#tableExpression}. * @param ctx the parse tree */ - void exitBooleanTest(@NotNull SELECTParser.BooleanTestContext ctx); + void exitTableExpression(@NotNull SELECTParser.TableExpressionContext ctx); /** * Enter a parse tree produced by {@link SELECTParser#truthValue}. @@ -52,26 +52,26 @@ public interface SELECTListener extends ParseTreeListener { void exitTruthValue(@NotNull SELECTParser.TruthValueContext ctx); /** - * Enter a parse tree produced by {@link SELECTParser#tablePrimary}. + * Enter a parse tree produced by {@link SELECTParser#namedColumnsJoin}. * @param ctx the parse tree */ - void enterTablePrimary(@NotNull SELECTParser.TablePrimaryContext ctx); + void enterNamedColumnsJoin(@NotNull SELECTParser.NamedColumnsJoinContext ctx); /** - * Exit a parse tree produced by {@link SELECTParser#tablePrimary}. + * Exit a parse tree produced by {@link SELECTParser#namedColumnsJoin}. * @param ctx the parse tree */ - void exitTablePrimary(@NotNull SELECTParser.TablePrimaryContext ctx); + void exitNamedColumnsJoin(@NotNull SELECTParser.NamedColumnsJoinContext ctx); /** - * Enter a parse tree produced by {@link SELECTParser#querySpecification}. + * Enter a parse tree produced by {@link SELECTParser#joinCondition}. * @param ctx the parse tree */ - void enterQuerySpecification(@NotNull SELECTParser.QuerySpecificationContext ctx); + void enterJoinCondition(@NotNull SELECTParser.JoinConditionContext ctx); /** - * Exit a parse tree produced by {@link SELECTParser#querySpecification}. + * Exit a parse tree produced by {@link SELECTParser#joinCondition}. * @param ctx the parse tree */ - void exitQuerySpecification(@NotNull SELECTParser.QuerySpecificationContext ctx); + void exitJoinCondition(@NotNull SELECTParser.JoinConditionContext ctx); /** * Enter a parse tree produced by {@link SELECTParser#selectList}. @@ -85,26 +85,26 @@ public interface SELECTListener extends ParseTreeListener { void exitSelectList(@NotNull SELECTParser.SelectListContext ctx); /** - * Enter a parse tree produced by {@link SELECTParser#booleanValueExpression}. + * Enter a parse tree produced by {@link SELECTParser#querySpecification}. * @param ctx the parse tree */ - void enterBooleanValueExpression(@NotNull SELECTParser.BooleanValueExpressionContext ctx); + void enterQuerySpecification(@NotNull SELECTParser.QuerySpecificationContext ctx); /** - * Exit a parse tree produced by {@link SELECTParser#booleanValueExpression}. + * Exit a parse tree produced by {@link SELECTParser#querySpecification}. * @param ctx the parse tree */ - void exitBooleanValueExpression(@NotNull SELECTParser.BooleanValueExpressionContext ctx); + void exitQuerySpecification(@NotNull SELECTParser.QuerySpecificationContext ctx); /** - * Enter a parse tree produced by {@link SELECTParser#derivedColumn}. + * Enter a parse tree produced by {@link SELECTParser#booleanTerm}. * @param ctx the parse tree */ - void enterDerivedColumn(@NotNull SELECTParser.DerivedColumnContext ctx); + void enterBooleanTerm(@NotNull SELECTParser.BooleanTermContext ctx); /** - * Exit a parse tree produced by {@link SELECTParser#derivedColumn}. + * Exit a parse tree produced by {@link SELECTParser#booleanTerm}. * @param ctx the parse tree */ - void exitDerivedColumn(@NotNull SELECTParser.DerivedColumnContext ctx); + void exitBooleanTerm(@NotNull SELECTParser.BooleanTermContext ctx); /** * Enter a parse tree produced by {@link SELECTParser#booleanPredicand}. @@ -118,15 +118,15 @@ public interface SELECTListener extends ParseTreeListener { void exitBooleanPredicand(@NotNull SELECTParser.BooleanPredicandContext ctx); /** - * Enter a parse tree produced by {@link SELECTParser#booleanTerm}. + * Enter a parse tree produced by {@link SELECTParser#unionJoin}. * @param ctx the parse tree */ - void enterBooleanTerm(@NotNull SELECTParser.BooleanTermContext ctx); + void enterUnionJoin(@NotNull SELECTParser.UnionJoinContext ctx); /** - * Exit a parse tree produced by {@link SELECTParser#booleanTerm}. + * Exit a parse tree produced by {@link SELECTParser#unionJoin}. * @param ctx the parse tree */ - void exitBooleanTerm(@NotNull SELECTParser.BooleanTermContext ctx); + void exitUnionJoin(@NotNull SELECTParser.UnionJoinContext ctx); /** * Enter a parse tree produced by {@link SELECTParser#booleanPrimary}. @@ -139,17 +139,6 @@ public interface SELECTListener extends ParseTreeListener { */ void exitBooleanPrimary(@NotNull SELECTParser.BooleanPrimaryContext ctx); - /** - * Enter a parse tree produced by {@link SELECTParser#tablePrimaryAs}. - * @param ctx the parse tree - */ - void enterTablePrimaryAs(@NotNull SELECTParser.TablePrimaryAsContext ctx); - /** - * Exit a parse tree produced by {@link SELECTParser#tablePrimaryAs}. - * @param ctx the parse tree - */ - void exitTablePrimaryAs(@NotNull SELECTParser.TablePrimaryAsContext ctx); - /** * Enter a parse tree produced by {@link SELECTParser#derivedColumnList}. * @param ctx the parse tree @@ -183,17 +172,6 @@ public interface SELECTListener extends ParseTreeListener { */ void exitTableName(@NotNull SELECTParser.TableNameContext ctx); - /** - * Enter a parse tree produced by {@link SELECTParser#parenthizedBooleanValueExpression}. - * @param ctx the parse tree - */ - void enterParenthizedBooleanValueExpression(@NotNull SELECTParser.ParenthizedBooleanValueExpressionContext ctx); - /** - * Exit a parse tree produced by {@link SELECTParser#parenthizedBooleanValueExpression}. - * @param ctx the parse tree - */ - void exitParenthizedBooleanValueExpression(@NotNull SELECTParser.ParenthizedBooleanValueExpressionContext ctx); - /** * Enter a parse tree produced by {@link SELECTParser#searchCondition}. * @param ctx the parse tree @@ -216,6 +194,171 @@ public interface SELECTListener extends ParseTreeListener { */ void exitColumnName(@NotNull SELECTParser.ColumnNameContext ctx); + /** + * Enter a parse tree produced by {@link SELECTParser#crossJoin}. + * @param ctx the parse tree + */ + void enterCrossJoin(@NotNull SELECTParser.CrossJoinContext ctx); + /** + * Exit a parse tree produced by {@link SELECTParser#crossJoin}. + * @param ctx the parse tree + */ + void exitCrossJoin(@NotNull SELECTParser.CrossJoinContext ctx); + + /** + * Enter a parse tree produced by {@link SELECTParser#selectStmnt}. + * @param ctx the parse tree + */ + void enterSelectStmnt(@NotNull SELECTParser.SelectStmntContext ctx); + /** + * Exit a parse tree produced by {@link SELECTParser#selectStmnt}. + * @param ctx the parse tree + */ + void exitSelectStmnt(@NotNull SELECTParser.SelectStmntContext ctx); + + /** + * Enter a parse tree produced by {@link SELECTParser#columnInTable}. + * @param ctx the parse tree + */ + void enterColumnInTable(@NotNull SELECTParser.ColumnInTableContext ctx); + /** + * Exit a parse tree produced by {@link SELECTParser#columnInTable}. + * @param ctx the parse tree + */ + void exitColumnInTable(@NotNull SELECTParser.ColumnInTableContext ctx); + + /** + * Enter a parse tree produced by {@link SELECTParser#joinSpec}. + * @param ctx the parse tree + */ + void enterJoinSpec(@NotNull SELECTParser.JoinSpecContext ctx); + /** + * Exit a parse tree produced by {@link SELECTParser#joinSpec}. + * @param ctx the parse tree + */ + void exitJoinSpec(@NotNull SELECTParser.JoinSpecContext ctx); + + /** + * Enter a parse tree produced by {@link SELECTParser#booleanTest}. + * @param ctx the parse tree + */ + void enterBooleanTest(@NotNull SELECTParser.BooleanTestContext ctx); + /** + * Exit a parse tree produced by {@link SELECTParser#booleanTest}. + * @param ctx the parse tree + */ + void exitBooleanTest(@NotNull SELECTParser.BooleanTestContext ctx); + + /** + * Enter a parse tree produced by {@link SELECTParser#parenthesizedBoolValueExpr}. + * @param ctx the parse tree + */ + void enterParenthesizedBoolValueExpr(@NotNull SELECTParser.ParenthesizedBoolValueExprContext ctx); + /** + * Exit a parse tree produced by {@link SELECTParser#parenthesizedBoolValueExpr}. + * @param ctx the parse tree + */ + void exitParenthesizedBoolValueExpr(@NotNull SELECTParser.ParenthesizedBoolValueExprContext ctx); + + /** + * Enter a parse tree produced by {@link SELECTParser#tablePrimary}. + * @param ctx the parse tree + */ + void enterTablePrimary(@NotNull SELECTParser.TablePrimaryContext ctx); + /** + * Exit a parse tree produced by {@link SELECTParser#tablePrimary}. + * @param ctx the parse tree + */ + void exitTablePrimary(@NotNull SELECTParser.TablePrimaryContext ctx); + + /** + * Enter a parse tree produced by {@link SELECTParser#freeColumn}. + * @param ctx the parse tree + */ + void enterFreeColumn(@NotNull SELECTParser.FreeColumnContext ctx); + /** + * Exit a parse tree produced by {@link SELECTParser#freeColumn}. + * @param ctx the parse tree + */ + void exitFreeColumn(@NotNull SELECTParser.FreeColumnContext ctx); + + /** + * Enter a parse tree produced by {@link SELECTParser#booleanValueExpression}. + * @param ctx the parse tree + */ + void enterBooleanValueExpression(@NotNull SELECTParser.BooleanValueExpressionContext ctx); + /** + * Exit a parse tree produced by {@link SELECTParser#booleanValueExpression}. + * @param ctx the parse tree + */ + void exitBooleanValueExpression(@NotNull SELECTParser.BooleanValueExpressionContext ctx); + + /** + * Enter a parse tree produced by {@link SELECTParser#joinClause}. + * @param ctx the parse tree + */ + void enterJoinClause(@NotNull SELECTParser.JoinClauseContext ctx); + /** + * Exit a parse tree produced by {@link SELECTParser#joinClause}. + * @param ctx the parse tree + */ + void exitJoinClause(@NotNull SELECTParser.JoinClauseContext ctx); + + /** + * Enter a parse tree produced by {@link SELECTParser#resultExpression}. + * @param ctx the parse tree + */ + void enterResultExpression(@NotNull SELECTParser.ResultExpressionContext ctx); + /** + * Exit a parse tree produced by {@link SELECTParser#resultExpression}. + * @param ctx the parse tree + */ + void exitResultExpression(@NotNull SELECTParser.ResultExpressionContext ctx); + + /** + * Enter a parse tree produced by {@link SELECTParser#tablePrimaryAs}. + * @param ctx the parse tree + */ + void enterTablePrimaryAs(@NotNull SELECTParser.TablePrimaryAsContext ctx); + /** + * Exit a parse tree produced by {@link SELECTParser#tablePrimaryAs}. + * @param ctx the parse tree + */ + void exitTablePrimaryAs(@NotNull SELECTParser.TablePrimaryAsContext ctx); + + /** + * Enter a parse tree produced by {@link SELECTParser#naturalJoin}. + * @param ctx the parse tree + */ + void enterNaturalJoin(@NotNull SELECTParser.NaturalJoinContext ctx); + /** + * Exit a parse tree produced by {@link SELECTParser#naturalJoin}. + * @param ctx the parse tree + */ + void exitNaturalJoin(@NotNull SELECTParser.NaturalJoinContext ctx); + + /** + * Enter a parse tree produced by {@link SELECTParser#column}. + * @param ctx the parse tree + */ + void enterColumn(@NotNull SELECTParser.ColumnContext ctx); + /** + * Exit a parse tree produced by {@link SELECTParser#column}. + * @param ctx the parse tree + */ + void exitColumn(@NotNull SELECTParser.ColumnContext ctx); + + /** + * Enter a parse tree produced by {@link SELECTParser#qualifiedJoin}. + * @param ctx the parse tree + */ + void enterQualifiedJoin(@NotNull SELECTParser.QualifiedJoinContext ctx); + /** + * Exit a parse tree produced by {@link SELECTParser#qualifiedJoin}. + * @param ctx the parse tree + */ + void exitQualifiedJoin(@NotNull SELECTParser.QualifiedJoinContext ctx); + /** * Enter a parse tree produced by {@link SELECTParser#asClause}. * @param ctx the parse tree @@ -239,15 +382,26 @@ public interface SELECTListener extends ParseTreeListener { void exitBooleanFactor(@NotNull SELECTParser.BooleanFactorContext ctx); /** - * Enter a parse tree produced by {@link SELECTParser#selectStmnt}. + * Enter a parse tree produced by {@link SELECTParser#joinType}. * @param ctx the parse tree */ - void enterSelectStmnt(@NotNull SELECTParser.SelectStmntContext ctx); + void enterJoinType(@NotNull SELECTParser.JoinTypeContext ctx); /** - * Exit a parse tree produced by {@link SELECTParser#selectStmnt}. + * Exit a parse tree produced by {@link SELECTParser#joinType}. * @param ctx the parse tree */ - void exitSelectStmnt(@NotNull SELECTParser.SelectStmntContext ctx); + void exitJoinType(@NotNull SELECTParser.JoinTypeContext ctx); + + /** + * Enter a parse tree produced by {@link SELECTParser#outerJoinType}. + * @param ctx the parse tree + */ + void enterOuterJoinType(@NotNull SELECTParser.OuterJoinTypeContext ctx); + /** + * Exit a parse tree produced by {@link SELECTParser#outerJoinType}. + * @param ctx the parse tree + */ + void exitOuterJoinType(@NotNull SELECTParser.OuterJoinTypeContext ctx); /** * Enter a parse tree produced by {@link SELECTParser#fromClause}. diff --git a/src/com/etk/parser/SELECTParser.java b/src/com/etk/parser/SELECTParser.java index 89e1d3c..9df26ba 100644 --- a/src/com/etk/parser/SELECTParser.java +++ b/src/com/etk/parser/SELECTParser.java @@ -12,34 +12,44 @@ import java.util.List; @SuppressWarnings({"all", "warnings", "unchecked", "unused", "cast"}) -public class SELECTParser extends Parser{ +public class SELECTParser extends Parser { protected static final DFA[] _decisionToDFA; protected static final PredictionContextCache _sharedContextCache = new PredictionContextCache(); public static final int - T__16=1, T__15=2, T__14=3, T__13=4, T__12=5, T__11=6, T__10=7, T__9=8, - T__8=9, T__7=10, T__6=11, T__5=12, T__4=13, T__3=14, T__2=15, T__1=16, - T__0=17, ID=18, WS=19; + T__28=1, T__27=2, T__26=3, T__25=4, T__24=5, T__23=6, T__22=7, T__21=8, + T__20=9, T__19=10, T__18=11, T__17=12, T__16=13, T__15=14, T__14=15, T__13=16, + T__12=17, T__11=18, T__10=19, T__9=20, T__8=21, T__7=22, T__6=23, T__5=24, + T__4=25, T__3=26, T__2=27, T__1=28, T__0=29, ID=30, WS=31; public static final String[] tokenNames = { - "", "'AS'", "'DISTINCT'", "'AND'", "'IS'", "'ALL'", "')'", "','", - "'OR'", "'*'", "'WHERE'", "'('", "'FROM'", "'TRUE'", "'UNKNOWN'", "'NOT'", - "'SELECT'", "'FALSE'", "ID", "WS" + "", "'CROSS JOIN'", "'DISTINCT'", "'ALL'", "','", "'RIGHT'", + "'*'", "'WHERE'", "'('", "'AS'", "'FULL'", "'OR'", "'TRUE'", "'JOIN'", + "'UNION JOIN'", "'FALSE'", "'AND'", "'USING'", "'INNER'", "'NATURAL'", + "'.'", "')'", "'LEFT'", "'UNKNOWN'", "'ON'", "'IS'", "'OUTER'", "'FROM'", + "'NOT'", "'SELECT'", "ID", "WS" }; public static final int RULE_selectStmnt = 0, RULE_querySpecification = 1, RULE_setQuantifier = 2, - RULE_selectList = 3, RULE_derivedColumn = 4, RULE_asClause = 5, RULE_tableExpression = 6, - RULE_fromClause = 7, RULE_tablePrimary = 8, RULE_tablePrimaryAs = 9, RULE_derivedColumnList = 10, - RULE_whereClause = 11, RULE_searchCondition = 12, RULE_booleanValueExpression = 13, - RULE_booleanTerm = 14, RULE_booleanFactor = 15, RULE_booleanTest = 16, - RULE_truthValue = 17, RULE_booleanPrimary = 18, RULE_booleanPredicand = 19, - RULE_parenthizedBooleanValueExpression = 20, RULE_columnName = 21, RULE_tableName = 22; + RULE_selectList = 3, RULE_column = 4, RULE_columnInTable = 5, RULE_freeColumn = 6, + RULE_asClause = 7, RULE_tableExpression = 8, RULE_fromClause = 9, RULE_tablePrimary = 10, + RULE_tablePrimaryAs = 11, RULE_derivedColumnList = 12, RULE_whereClause = 13, + RULE_searchCondition = 14, RULE_booleanValueExpression = 15, RULE_booleanTerm = 16, + RULE_booleanFactor = 17, RULE_booleanTest = 18, RULE_truthValue = 19, + RULE_booleanPrimary = 20, RULE_booleanPredicand = 21, RULE_parenthesizedBoolValueExpr = 22, + RULE_resultExpression = 23, RULE_joinClause = 24, RULE_crossJoin = 25, + RULE_qualifiedJoin = 26, RULE_naturalJoin = 27, RULE_unionJoin = 28, RULE_joinType = 29, + RULE_outerJoinType = 30, RULE_joinSpec = 31, RULE_joinCondition = 32, + RULE_namedColumnsJoin = 33, RULE_columnNameList = 34, RULE_columnName = 35, + RULE_tableName = 36; public static final String[] ruleNames = { - "selectStmnt", "querySpecification", "setQuantifier", "selectList", "derivedColumn", - "asClause", "tableExpression", "fromClause", "tablePrimary", "tablePrimaryAs", - "derivedColumnList", "whereClause", "searchCondition", "booleanValueExpression", - "booleanTerm", "booleanFactor", "booleanTest", "truthValue", "booleanPrimary", - "booleanPredicand", "parenthizedBooleanValueExpression", "columnName", - "tableName" + "selectStmnt", "querySpecification", "setQuantifier", "selectList", "column", + "columnInTable", "freeColumn", "asClause", "tableExpression", "fromClause", + "tablePrimary", "tablePrimaryAs", "derivedColumnList", "whereClause", + "searchCondition", "booleanValueExpression", "booleanTerm", "booleanFactor", + "booleanTest", "truthValue", "booleanPrimary", "booleanPredicand", "parenthesizedBoolValueExpr", + "resultExpression", "joinClause", "crossJoin", "qualifiedJoin", "naturalJoin", + "unionJoin", "joinType", "outerJoinType", "joinSpec", "joinCondition", + "namedColumnsJoin", "columnNameList", "columnName", "tableName" }; @Override @@ -82,8 +92,8 @@ public final SelectStmntContext selectStmnt() throws RecognitionException { try { enterOuterAlt(_localctx, 1); { - setState(46); match(16); - setState(47); querySpecification(); + setState(74); match(29); + setState(75); querySpecification(); } } catch (RecognitionException re) { @@ -98,6 +108,9 @@ public final SelectStmntContext selectStmnt() throws RecognitionException { } public static class QuerySpecificationContext extends ParserRuleContext { + public ResultExpressionContext resultExpression() { + return getRuleContext(ResultExpressionContext.class,0); + } public SelectListContext selectList() { return getRuleContext(SelectListContext.class,0); } @@ -128,16 +141,24 @@ public final QuerySpecificationContext querySpecification() throws RecognitionEx try { enterOuterAlt(_localctx, 1); { - setState(50); + setState(78); + _la = _input.LA(1); + if (_la==2 || _la==3) { + { + setState(77); setQuantifier(); + } + } + + setState(80); selectList(); + setState(81); tableExpression(); + setState(83); _la = _input.LA(1); - if (_la==2 || _la==5) { + if ((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << 1) | (1L << 5) | (1L << 10) | (1L << 14) | (1L << 18) | (1L << 19) | (1L << 22))) != 0)) { { - setState(49); setQuantifier(); + setState(82); resultExpression(); } } - setState(52); selectList(); - setState(53); tableExpression(); } } catch (RecognitionException re) { @@ -173,9 +194,9 @@ public final SetQuantifierContext setQuantifier() throws RecognitionException { try { enterOuterAlt(_localctx, 1); { - setState(55); + setState(85); _la = _input.LA(1); - if ( !(_la==2 || _la==5) ) { + if ( !(_la==2 || _la==3) ) { _errHandler.recoverInline(this); } consume(); @@ -193,11 +214,11 @@ public final SetQuantifierContext setQuantifier() throws RecognitionException { } public static class SelectListContext extends ParserRuleContext { - public DerivedColumnContext derivedColumn(int i) { - return getRuleContext(DerivedColumnContext.class,i); + public ColumnContext column(int i) { + return getRuleContext(ColumnContext.class,i); } - public List derivedColumn() { - return getRuleContexts(DerivedColumnContext.class); + public List column() { + return getRuleContexts(ColumnContext.class); } public SelectListContext(ParserRuleContext parent, int invokingState) { super(parent, invokingState); @@ -218,29 +239,29 @@ public final SelectListContext selectList() throws RecognitionException { enterRule(_localctx, 6, RULE_selectList); int _la; try { - setState(66); + setState(96); switch (_input.LA(1)) { - case 9: + case 6: enterOuterAlt(_localctx, 1); { - setState(57); match(9); + setState(87); match(6); } break; case ID: enterOuterAlt(_localctx, 2); { - setState(58); derivedColumn(); - setState(63); + setState(88); column(); + setState(93); _errHandler.sync(this); _la = _input.LA(1); - while (_la==7) { + while (_la==4) { { { - setState(59); match(7); - setState(60); derivedColumn(); + setState(89); match(4); + setState(90); column(); } } - setState(65); + setState(95); _errHandler.sync(this); _la = _input.LA(1); } @@ -261,40 +282,136 @@ public final SelectListContext selectList() throws RecognitionException { return _localctx; } - public static class DerivedColumnContext extends ParserRuleContext { + public static class ColumnContext extends ParserRuleContext { + public ColumnInTableContext columnInTable() { + return getRuleContext(ColumnInTableContext.class,0); + } + public FreeColumnContext freeColumn() { + return getRuleContext(FreeColumnContext.class,0); + } + public ColumnContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_column; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof SELECTListener ) ((SELECTListener)listener).enterColumn(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof SELECTListener ) ((SELECTListener)listener).exitColumn(this); + } + } + + public final ColumnContext column() throws RecognitionException { + ColumnContext _localctx = new ColumnContext(_ctx, getState()); + enterRule(_localctx, 8, RULE_column); + try { + setState(100); + switch ( getInterpreter().adaptivePredict(_input,4,_ctx) ) { + case 1: + enterOuterAlt(_localctx, 1); + { + setState(98); columnInTable(); + } + break; + + case 2: + enterOuterAlt(_localctx, 2); + { + setState(99); freeColumn(); + } + break; + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + public static class ColumnInTableContext extends ParserRuleContext { + public ColumnNameContext columnName() { + return getRuleContext(ColumnNameContext.class,0); + } + public TableNameContext tableName() { + return getRuleContext(TableNameContext.class,0); + } + public ColumnInTableContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_columnInTable; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof SELECTListener ) ((SELECTListener)listener).enterColumnInTable(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof SELECTListener ) ((SELECTListener)listener).exitColumnInTable(this); + } + } + + public final ColumnInTableContext columnInTable() throws RecognitionException { + ColumnInTableContext _localctx = new ColumnInTableContext(_ctx, getState()); + enterRule(_localctx, 10, RULE_columnInTable); + try { + enterOuterAlt(_localctx, 1); + { + setState(102); tableName(); + setState(103); match(20); + setState(104); columnName(); + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + public static class FreeColumnContext extends ParserRuleContext { public AsClauseContext asClause() { return getRuleContext(AsClauseContext.class,0); } public ColumnNameContext columnName() { return getRuleContext(ColumnNameContext.class,0); } - public DerivedColumnContext(ParserRuleContext parent, int invokingState) { + public FreeColumnContext(ParserRuleContext parent, int invokingState) { super(parent, invokingState); } - @Override public int getRuleIndex() { return RULE_derivedColumn; } + @Override public int getRuleIndex() { return RULE_freeColumn; } @Override public void enterRule(ParseTreeListener listener) { - if ( listener instanceof SELECTListener ) ((SELECTListener)listener).enterDerivedColumn(this); + if ( listener instanceof SELECTListener ) ((SELECTListener)listener).enterFreeColumn(this); } @Override public void exitRule(ParseTreeListener listener) { - if ( listener instanceof SELECTListener ) ((SELECTListener)listener).exitDerivedColumn(this); + if ( listener instanceof SELECTListener ) ((SELECTListener)listener).exitFreeColumn(this); } } - public final DerivedColumnContext derivedColumn() throws RecognitionException { - DerivedColumnContext _localctx = new DerivedColumnContext(_ctx, getState()); - enterRule(_localctx, 8, RULE_derivedColumn); + public final FreeColumnContext freeColumn() throws RecognitionException { + FreeColumnContext _localctx = new FreeColumnContext(_ctx, getState()); + enterRule(_localctx, 12, RULE_freeColumn); int _la; try { enterOuterAlt(_localctx, 1); { - setState(68); columnName(); - setState(70); + setState(106); columnName(); + setState(108); _la = _input.LA(1); - if (_la==1) { + if (_la==9) { { - setState(69); asClause(); + setState(107); asClause(); } } @@ -331,12 +448,12 @@ public void exitRule(ParseTreeListener listener) { public final AsClauseContext asClause() throws RecognitionException { AsClauseContext _localctx = new AsClauseContext(_ctx, getState()); - enterRule(_localctx, 10, RULE_asClause); + enterRule(_localctx, 14, RULE_asClause); try { enterOuterAlt(_localctx, 1); { - setState(72); match(1); - setState(73); columnName(); + setState(110); match(9); + setState(111); columnName(); } } catch (RecognitionException re) { @@ -370,11 +487,11 @@ public void exitRule(ParseTreeListener listener) { public final TableExpressionContext tableExpression() throws RecognitionException { TableExpressionContext _localctx = new TableExpressionContext(_ctx, getState()); - enterRule(_localctx, 12, RULE_tableExpression); + enterRule(_localctx, 16, RULE_tableExpression); try { enterOuterAlt(_localctx, 1); { - setState(75); fromClause(); + setState(113); fromClause(); } } catch (RecognitionException re) { @@ -411,24 +528,24 @@ public void exitRule(ParseTreeListener listener) { public final FromClauseContext fromClause() throws RecognitionException { FromClauseContext _localctx = new FromClauseContext(_ctx, getState()); - enterRule(_localctx, 14, RULE_fromClause); + enterRule(_localctx, 18, RULE_fromClause); int _la; try { enterOuterAlt(_localctx, 1); { - setState(77); match(12); - setState(78); tablePrimary(); - setState(83); + setState(115); match(27); + setState(116); tablePrimary(); + setState(121); _errHandler.sync(this); _la = _input.LA(1); - while (_la==7) { + while (_la==4) { { { - setState(79); match(7); - setState(80); tablePrimary(); + setState(117); match(4); + setState(118); tablePrimary(); } } - setState(85); + setState(123); _errHandler.sync(this); _la = _input.LA(1); } @@ -468,18 +585,18 @@ public void exitRule(ParseTreeListener listener) { public final TablePrimaryContext tablePrimary() throws RecognitionException { TablePrimaryContext _localctx = new TablePrimaryContext(_ctx, getState()); - enterRule(_localctx, 16, RULE_tablePrimary); + enterRule(_localctx, 20, RULE_tablePrimary); int _la; try { enterOuterAlt(_localctx, 1); { - setState(86); tableName(); - setState(89); + setState(124); tableName(); + setState(127); _la = _input.LA(1); - if (_la==1) { + if (_la==9) { { - setState(87); match(1); - setState(88); tablePrimaryAs(); + setState(125); match(9); + setState(126); tablePrimaryAs(); } } @@ -519,19 +636,19 @@ public void exitRule(ParseTreeListener listener) { public final TablePrimaryAsContext tablePrimaryAs() throws RecognitionException { TablePrimaryAsContext _localctx = new TablePrimaryAsContext(_ctx, getState()); - enterRule(_localctx, 18, RULE_tablePrimaryAs); + enterRule(_localctx, 22, RULE_tablePrimaryAs); int _la; try { enterOuterAlt(_localctx, 1); { - setState(91); tableName(); - setState(96); + setState(129); tableName(); + setState(134); _la = _input.LA(1); - if (_la==11) { + if (_la==8) { { - setState(92); match(11); - setState(93); derivedColumnList(); - setState(94); match(6); + setState(130); match(8); + setState(131); derivedColumnList(); + setState(132); match(21); } } @@ -571,23 +688,23 @@ public void exitRule(ParseTreeListener listener) { public final DerivedColumnListContext derivedColumnList() throws RecognitionException { DerivedColumnListContext _localctx = new DerivedColumnListContext(_ctx, getState()); - enterRule(_localctx, 20, RULE_derivedColumnList); + enterRule(_localctx, 24, RULE_derivedColumnList); int _la; try { enterOuterAlt(_localctx, 1); { - setState(98); columnName(); - setState(103); + setState(136); columnName(); + setState(141); _errHandler.sync(this); _la = _input.LA(1); - while (_la==7) { + while (_la==4) { { { - setState(99); match(7); - setState(100); columnName(); + setState(137); match(4); + setState(138); columnName(); } } - setState(105); + setState(143); _errHandler.sync(this); _la = _input.LA(1); } @@ -624,12 +741,12 @@ public void exitRule(ParseTreeListener listener) { public final WhereClauseContext whereClause() throws RecognitionException { WhereClauseContext _localctx = new WhereClauseContext(_ctx, getState()); - enterRule(_localctx, 22, RULE_whereClause); + enterRule(_localctx, 26, RULE_whereClause); try { enterOuterAlt(_localctx, 1); { - setState(106); match(10); - setState(107); searchCondition(); + setState(144); match(7); + setState(145); searchCondition(); } } catch (RecognitionException re) { @@ -663,11 +780,11 @@ public void exitRule(ParseTreeListener listener) { public final SearchConditionContext searchCondition() throws RecognitionException { SearchConditionContext _localctx = new SearchConditionContext(_ctx, getState()); - enterRule(_localctx, 24, RULE_searchCondition); + enterRule(_localctx, 28, RULE_searchCondition); try { enterOuterAlt(_localctx, 1); { - setState(109); booleanValueExpression(0); + setState(147); booleanValueExpression(0); } } catch (RecognitionException re) { @@ -710,19 +827,19 @@ public final BooleanValueExpressionContext booleanValueExpression(int _p) throws int _parentState = getState(); BooleanValueExpressionContext _localctx = new BooleanValueExpressionContext(_ctx, _parentState, _p); BooleanValueExpressionContext _prevctx = _localctx; - int _startState = 26; + int _startState = 30; enterRecursionRule(_localctx, RULE_booleanValueExpression); try { int _alt; enterOuterAlt(_localctx, 1); { { - setState(112); booleanTerm(0); + setState(150); booleanTerm(0); } _ctx.stop = _input.LT(-1); - setState(119); + setState(157); _errHandler.sync(this); - _alt = getInterpreter().adaptivePredict(_input,8,_ctx); + _alt = getInterpreter().adaptivePredict(_input,10,_ctx); while ( _alt!=2 && _alt!=-1 ) { if ( _alt==1 ) { if ( _parseListeners!=null ) triggerExitRuleEvent(); @@ -731,16 +848,16 @@ public final BooleanValueExpressionContext booleanValueExpression(int _p) throws { _localctx = new BooleanValueExpressionContext(_parentctx, _parentState, _p); pushNewRecursionContext(_localctx, _startState, RULE_booleanValueExpression); - setState(114); + setState(152); if (!(1 >= _localctx._p)) throw new FailedPredicateException(this, "1 >= $_p"); - setState(115); match(8); - setState(116); booleanTerm(0); + setState(153); match(11); + setState(154); booleanTerm(0); } } } - setState(121); + setState(159); _errHandler.sync(this); - _alt = getInterpreter().adaptivePredict(_input,8,_ctx); + _alt = getInterpreter().adaptivePredict(_input,10,_ctx); } } } @@ -784,19 +901,19 @@ public final BooleanTermContext booleanTerm(int _p) throws RecognitionException int _parentState = getState(); BooleanTermContext _localctx = new BooleanTermContext(_ctx, _parentState, _p); BooleanTermContext _prevctx = _localctx; - int _startState = 28; + int _startState = 32; enterRecursionRule(_localctx, RULE_booleanTerm); try { int _alt; enterOuterAlt(_localctx, 1); { { - setState(123); booleanFactor(); + setState(161); booleanFactor(); } _ctx.stop = _input.LT(-1); - setState(130); + setState(168); _errHandler.sync(this); - _alt = getInterpreter().adaptivePredict(_input,9,_ctx); + _alt = getInterpreter().adaptivePredict(_input,11,_ctx); while ( _alt!=2 && _alt!=-1 ) { if ( _alt==1 ) { if ( _parseListeners!=null ) triggerExitRuleEvent(); @@ -805,16 +922,16 @@ public final BooleanTermContext booleanTerm(int _p) throws RecognitionException { _localctx = new BooleanTermContext(_parentctx, _parentState, _p); pushNewRecursionContext(_localctx, _startState, RULE_booleanTerm); - setState(125); + setState(163); if (!(1 >= _localctx._p)) throw new FailedPredicateException(this, "1 >= $_p"); - setState(126); match(3); - setState(127); booleanFactor(); + setState(164); match(16); + setState(165); booleanFactor(); } } } - setState(132); + setState(170); _errHandler.sync(this); - _alt = getInterpreter().adaptivePredict(_input,9,_ctx); + _alt = getInterpreter().adaptivePredict(_input,11,_ctx); } } } @@ -849,20 +966,20 @@ public void exitRule(ParseTreeListener listener) { public final BooleanFactorContext booleanFactor() throws RecognitionException { BooleanFactorContext _localctx = new BooleanFactorContext(_ctx, getState()); - enterRule(_localctx, 30, RULE_booleanFactor); + enterRule(_localctx, 34, RULE_booleanFactor); int _la; try { enterOuterAlt(_localctx, 1); { - setState(134); + setState(172); _la = _input.LA(1); - if (_la==15) { + if (_la==28) { { - setState(133); match(15); + setState(171); match(28); } } - setState(136); booleanTest(); + setState(174); booleanTest(); } } catch (RecognitionException re) { @@ -899,26 +1016,26 @@ public void exitRule(ParseTreeListener listener) { public final BooleanTestContext booleanTest() throws RecognitionException { BooleanTestContext _localctx = new BooleanTestContext(_ctx, getState()); - enterRule(_localctx, 32, RULE_booleanTest); + enterRule(_localctx, 36, RULE_booleanTest); int _la; try { enterOuterAlt(_localctx, 1); { - setState(138); booleanPrimary(); - setState(144); - switch ( getInterpreter().adaptivePredict(_input,12,_ctx) ) { + setState(176); booleanPrimary(); + setState(182); + switch ( getInterpreter().adaptivePredict(_input,14,_ctx) ) { case 1: { - setState(139); match(4); - setState(141); + setState(177); match(25); + setState(179); _la = _input.LA(1); - if (_la==15) { + if (_la==28) { { - setState(140); match(15); + setState(178); match(28); } } - setState(143); truthValue(); + setState(181); truthValue(); } break; } @@ -952,14 +1069,14 @@ public void exitRule(ParseTreeListener listener) { public final TruthValueContext truthValue() throws RecognitionException { TruthValueContext _localctx = new TruthValueContext(_ctx, getState()); - enterRule(_localctx, 34, RULE_truthValue); + enterRule(_localctx, 38, RULE_truthValue); int _la; try { enterOuterAlt(_localctx, 1); { - setState(146); + setState(184); _la = _input.LA(1); - if ( !((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << 13) | (1L << 14) | (1L << 17))) != 0)) ) { + if ( !((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << 12) | (1L << 15) | (1L << 23))) != 0)) ) { _errHandler.recoverInline(this); } consume(); @@ -996,11 +1113,11 @@ public void exitRule(ParseTreeListener listener) { public final BooleanPrimaryContext booleanPrimary() throws RecognitionException { BooleanPrimaryContext _localctx = new BooleanPrimaryContext(_ctx, getState()); - enterRule(_localctx, 36, RULE_booleanPrimary); + enterRule(_localctx, 40, RULE_booleanPrimary); try { enterOuterAlt(_localctx, 1); { - setState(148); booleanPredicand(); + setState(186); booleanPredicand(); } } catch (RecognitionException re) { @@ -1015,8 +1132,8 @@ public final BooleanPrimaryContext booleanPrimary() throws RecognitionException } public static class BooleanPredicandContext extends ParserRuleContext { - public ParenthizedBooleanValueExpressionContext parenthizedBooleanValueExpression() { - return getRuleContext(ParenthizedBooleanValueExpressionContext.class,0); + public ParenthesizedBoolValueExprContext parenthesizedBoolValueExpr() { + return getRuleContext(ParenthesizedBoolValueExprContext.class,0); } public BooleanPredicandContext(ParserRuleContext parent, int invokingState) { super(parent, invokingState); @@ -1034,11 +1151,11 @@ public void exitRule(ParseTreeListener listener) { public final BooleanPredicandContext booleanPredicand() throws RecognitionException { BooleanPredicandContext _localctx = new BooleanPredicandContext(_ctx, getState()); - enterRule(_localctx, 38, RULE_booleanPredicand); + enterRule(_localctx, 42, RULE_booleanPredicand); try { enterOuterAlt(_localctx, 1); { - setState(150); parenthizedBooleanValueExpression(); + setState(188); parenthesizedBoolValueExpr(); } } catch (RecognitionException re) { @@ -1052,33 +1169,608 @@ public final BooleanPredicandContext booleanPredicand() throws RecognitionExcept return _localctx; } - public static class ParenthizedBooleanValueExpressionContext extends ParserRuleContext { + public static class ParenthesizedBoolValueExprContext extends ParserRuleContext { public BooleanValueExpressionContext booleanValueExpression() { return getRuleContext(BooleanValueExpressionContext.class,0); } - public ParenthizedBooleanValueExpressionContext(ParserRuleContext parent, int invokingState) { + public ParenthesizedBoolValueExprContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_parenthesizedBoolValueExpr; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof SELECTListener ) ((SELECTListener)listener).enterParenthesizedBoolValueExpr(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof SELECTListener ) ((SELECTListener)listener).exitParenthesizedBoolValueExpr(this); + } + } + + public final ParenthesizedBoolValueExprContext parenthesizedBoolValueExpr() throws RecognitionException { + ParenthesizedBoolValueExprContext _localctx = new ParenthesizedBoolValueExprContext(_ctx, getState()); + enterRule(_localctx, 44, RULE_parenthesizedBoolValueExpr); + try { + enterOuterAlt(_localctx, 1); + { + setState(190); match(8); + setState(191); booleanValueExpression(0); + setState(192); match(21); + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + public static class ResultExpressionContext extends ParserRuleContext { + public JoinClauseContext joinClause() { + return getRuleContext(JoinClauseContext.class,0); + } + public ResultExpressionContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_resultExpression; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof SELECTListener ) ((SELECTListener)listener).enterResultExpression(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof SELECTListener ) ((SELECTListener)listener).exitResultExpression(this); + } + } + + public final ResultExpressionContext resultExpression() throws RecognitionException { + ResultExpressionContext _localctx = new ResultExpressionContext(_ctx, getState()); + enterRule(_localctx, 46, RULE_resultExpression); + try { + enterOuterAlt(_localctx, 1); + { + setState(194); joinClause(); + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + public static class JoinClauseContext extends ParserRuleContext { + public QualifiedJoinContext qualifiedJoin() { + return getRuleContext(QualifiedJoinContext.class,0); + } + public CrossJoinContext crossJoin() { + return getRuleContext(CrossJoinContext.class,0); + } + public UnionJoinContext unionJoin() { + return getRuleContext(UnionJoinContext.class,0); + } + public NaturalJoinContext naturalJoin() { + return getRuleContext(NaturalJoinContext.class,0); + } + public JoinClauseContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_joinClause; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof SELECTListener ) ((SELECTListener)listener).enterJoinClause(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof SELECTListener ) ((SELECTListener)listener).exitJoinClause(this); + } + } + + public final JoinClauseContext joinClause() throws RecognitionException { + JoinClauseContext _localctx = new JoinClauseContext(_ctx, getState()); + enterRule(_localctx, 48, RULE_joinClause); + try { + setState(200); + switch (_input.LA(1)) { + case 1: + enterOuterAlt(_localctx, 1); + { + setState(196); crossJoin(); + } + break; + case 5: + case 10: + case 18: + case 22: + enterOuterAlt(_localctx, 2); + { + setState(197); qualifiedJoin(); + } + break; + case 19: + enterOuterAlt(_localctx, 3); + { + setState(198); naturalJoin(); + } + break; + case 14: + enterOuterAlt(_localctx, 4); + { + setState(199); unionJoin(); + } + break; + default: + throw new NoViableAltException(this); + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + public static class CrossJoinContext extends ParserRuleContext { + public TableNameContext tableName() { + return getRuleContext(TableNameContext.class, 0); + } + public CrossJoinContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_crossJoin; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof SELECTListener ) ((SELECTListener)listener).enterCrossJoin(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof SELECTListener ) ((SELECTListener)listener).exitCrossJoin(this); + } + } + + public final CrossJoinContext crossJoin() throws RecognitionException { + CrossJoinContext _localctx = new CrossJoinContext(_ctx, getState()); + enterRule(_localctx, 50, RULE_crossJoin); + try { + enterOuterAlt(_localctx, 1); + { + setState(202); match(1); + setState(203); tableName(); + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + public static class QualifiedJoinContext extends ParserRuleContext { + public JoinSpecContext joinSpec() { + return getRuleContext(JoinSpecContext.class,0); + } + public TableNameContext tableName() { + return getRuleContext(TableNameContext.class, 0); + } + public JoinTypeContext joinType() { + return getRuleContext(JoinTypeContext.class,0); + } + public QualifiedJoinContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_qualifiedJoin; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof SELECTListener ) ((SELECTListener)listener).enterQualifiedJoin(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof SELECTListener ) ((SELECTListener)listener).exitQualifiedJoin(this); + } + } + + public final QualifiedJoinContext qualifiedJoin() throws RecognitionException { + QualifiedJoinContext _localctx = new QualifiedJoinContext(_ctx, getState()); + enterRule(_localctx, 52, RULE_qualifiedJoin); + try { + enterOuterAlt(_localctx, 1); + { + setState(205); joinType(); + setState(206); match(13); + setState(207); tableName(); + setState(208); joinSpec(); + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + public static class NaturalJoinContext extends ParserRuleContext { + public TableNameContext tableName() { + return getRuleContext(TableNameContext.class, 0); + } + public JoinTypeContext joinType() { + return getRuleContext(JoinTypeContext.class,0); + } + public NaturalJoinContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_naturalJoin; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof SELECTListener ) ((SELECTListener)listener).enterNaturalJoin(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof SELECTListener ) ((SELECTListener)listener).exitNaturalJoin(this); + } + } + + public final NaturalJoinContext naturalJoin() throws RecognitionException { + NaturalJoinContext _localctx = new NaturalJoinContext(_ctx, getState()); + enterRule(_localctx, 54, RULE_naturalJoin); + try { + enterOuterAlt(_localctx, 1); + { + setState(210); match(19); + setState(211); joinType(); + setState(212); match(13); + setState(213); tableName(); + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + public static class UnionJoinContext extends ParserRuleContext { + public TableNameContext tableName() { + return getRuleContext(TableNameContext.class, 0); + } + public UnionJoinContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_unionJoin; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof SELECTListener ) ((SELECTListener)listener).enterUnionJoin(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof SELECTListener ) ((SELECTListener)listener).exitUnionJoin(this); + } + } + + public final UnionJoinContext unionJoin() throws RecognitionException { + UnionJoinContext _localctx = new UnionJoinContext(_ctx, getState()); + enterRule(_localctx, 56, RULE_unionJoin); + try { + enterOuterAlt(_localctx, 1); + { + setState(215); match(14); + setState(216); tableName(); + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + public static class JoinTypeContext extends ParserRuleContext { + public OuterJoinTypeContext outerJoinType() { + return getRuleContext(OuterJoinTypeContext.class,0); + } + public JoinTypeContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_joinType; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof SELECTListener ) ((SELECTListener)listener).enterJoinType(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof SELECTListener ) ((SELECTListener)listener).exitJoinType(this); + } + } + + public final JoinTypeContext joinType() throws RecognitionException { + JoinTypeContext _localctx = new JoinTypeContext(_ctx, getState()); + enterRule(_localctx, 58, RULE_joinType); + int _la; + try { + setState(223); + switch (_input.LA(1)) { + case 18: + enterOuterAlt(_localctx, 1); + { + setState(218); match(18); + } + break; + case 5: + case 10: + case 22: + enterOuterAlt(_localctx, 2); + { + setState(219); outerJoinType(); + setState(221); + _la = _input.LA(1); + if (_la==26) { + { + setState(220); match(26); + } + } + + } + break; + default: + throw new NoViableAltException(this); + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + public static class OuterJoinTypeContext extends ParserRuleContext { + public OuterJoinTypeContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_outerJoinType; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof SELECTListener ) ((SELECTListener)listener).enterOuterJoinType(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof SELECTListener ) ((SELECTListener)listener).exitOuterJoinType(this); + } + } + + public final OuterJoinTypeContext outerJoinType() throws RecognitionException { + OuterJoinTypeContext _localctx = new OuterJoinTypeContext(_ctx, getState()); + enterRule(_localctx, 60, RULE_outerJoinType); + int _la; + try { + enterOuterAlt(_localctx, 1); + { + setState(225); + _la = _input.LA(1); + if ( !((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << 5) | (1L << 10) | (1L << 22))) != 0)) ) { + _errHandler.recoverInline(this); + } + consume(); + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + public static class JoinSpecContext extends ParserRuleContext { + public NamedColumnsJoinContext namedColumnsJoin() { + return getRuleContext(NamedColumnsJoinContext.class,0); + } + public JoinConditionContext joinCondition() { + return getRuleContext(JoinConditionContext.class,0); + } + public JoinSpecContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_joinSpec; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof SELECTListener ) ((SELECTListener)listener).enterJoinSpec(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof SELECTListener ) ((SELECTListener)listener).exitJoinSpec(this); + } + } + + public final JoinSpecContext joinSpec() throws RecognitionException { + JoinSpecContext _localctx = new JoinSpecContext(_ctx, getState()); + enterRule(_localctx, 62, RULE_joinSpec); + try { + setState(229); + switch (_input.LA(1)) { + case 24: + enterOuterAlt(_localctx, 1); + { + setState(227); joinCondition(); + } + break; + case 17: + enterOuterAlt(_localctx, 2); + { + setState(228); namedColumnsJoin(); + } + break; + default: + throw new NoViableAltException(this); + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + public static class JoinConditionContext extends ParserRuleContext { + public SearchConditionContext searchCondition() { + return getRuleContext(SearchConditionContext.class,0); + } + public JoinConditionContext(ParserRuleContext parent, int invokingState) { super(parent, invokingState); } - @Override public int getRuleIndex() { return RULE_parenthizedBooleanValueExpression; } + @Override public int getRuleIndex() { return RULE_joinCondition; } @Override public void enterRule(ParseTreeListener listener) { - if ( listener instanceof SELECTListener ) ((SELECTListener)listener).enterParenthizedBooleanValueExpression(this); + if ( listener instanceof SELECTListener ) ((SELECTListener)listener).enterJoinCondition(this); } @Override public void exitRule(ParseTreeListener listener) { - if ( listener instanceof SELECTListener ) ((SELECTListener)listener).exitParenthizedBooleanValueExpression(this); + if ( listener instanceof SELECTListener ) ((SELECTListener)listener).exitJoinCondition(this); } } - public final ParenthizedBooleanValueExpressionContext parenthizedBooleanValueExpression() throws RecognitionException { - ParenthizedBooleanValueExpressionContext _localctx = new ParenthizedBooleanValueExpressionContext(_ctx, getState()); - enterRule(_localctx, 40, RULE_parenthizedBooleanValueExpression); + public final JoinConditionContext joinCondition() throws RecognitionException { + JoinConditionContext _localctx = new JoinConditionContext(_ctx, getState()); + enterRule(_localctx, 64, RULE_joinCondition); try { enterOuterAlt(_localctx, 1); { - setState(152); match(11); - setState(153); booleanValueExpression(0); - setState(154); match(6); + setState(231); match(24); + setState(232); searchCondition(); + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + public static class NamedColumnsJoinContext extends ParserRuleContext { + public ColumnNameListContext columnNameList() { + return getRuleContext(ColumnNameListContext.class,0); + } + public NamedColumnsJoinContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_namedColumnsJoin; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof SELECTListener ) ((SELECTListener)listener).enterNamedColumnsJoin(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof SELECTListener ) ((SELECTListener)listener).exitNamedColumnsJoin(this); + } + } + + public final NamedColumnsJoinContext namedColumnsJoin() throws RecognitionException { + NamedColumnsJoinContext _localctx = new NamedColumnsJoinContext(_ctx, getState()); + enterRule(_localctx, 66, RULE_namedColumnsJoin); + try { + enterOuterAlt(_localctx, 1); + { + setState(234); match(17); + setState(235); match(8); + setState(236); columnNameList(); + setState(237); match(21); + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + public static class ColumnNameListContext extends ParserRuleContext { + public ColumnNameContext columnName(int i) { + return getRuleContext(ColumnNameContext.class,i); + } + public List columnName() { + return getRuleContexts(ColumnNameContext.class); + } + public ColumnNameListContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_columnNameList; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof SELECTListener ) ((SELECTListener)listener).enterColumnNameList(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof SELECTListener ) ((SELECTListener)listener).exitColumnNameList(this); + } + } + + public final ColumnNameListContext columnNameList() throws RecognitionException { + ColumnNameListContext _localctx = new ColumnNameListContext(_ctx, getState()); + enterRule(_localctx, 68, RULE_columnNameList); + int _la; + try { + enterOuterAlt(_localctx, 1); + { + setState(239); columnName(); + setState(244); + _errHandler.sync(this); + _la = _input.LA(1); + while (_la==4) { + { + { + setState(240); match(4); + setState(241); columnName(); + } + } + setState(246); + _errHandler.sync(this); + _la = _input.LA(1); + } } } catch (RecognitionException re) { @@ -1110,11 +1802,11 @@ public void exitRule(ParseTreeListener listener) { public final ColumnNameContext columnName() throws RecognitionException { ColumnNameContext _localctx = new ColumnNameContext(_ctx, getState()); - enterRule(_localctx, 42, RULE_columnName); + enterRule(_localctx, 70, RULE_columnName); try { enterOuterAlt(_localctx, 1); { - setState(156); match(ID); + setState(247); match(ID); } } catch (RecognitionException re) { @@ -1146,11 +1838,11 @@ public void exitRule(ParseTreeListener listener) { public final TableNameContext tableName() throws RecognitionException { TableNameContext _localctx = new TableNameContext(_ctx, getState()); - enterRule(_localctx, 44, RULE_tableName); + enterRule(_localctx, 72, RULE_tableName); try { enterOuterAlt(_localctx, 1); { - setState(158); match(ID); + setState(249); match(ID); } } catch (RecognitionException re) { @@ -1166,9 +1858,9 @@ public final TableNameContext tableName() throws RecognitionException { public boolean sempred(RuleContext _localctx, int ruleIndex, int predIndex) { switch (ruleIndex) { - case 13: return booleanValueExpression_sempred((BooleanValueExpressionContext)_localctx, predIndex); + case 15: return booleanValueExpression_sempred((BooleanValueExpressionContext)_localctx, predIndex); - case 14: return booleanTerm_sempred((BooleanTermContext)_localctx, predIndex); + case 16: return booleanTerm_sempred((BooleanTermContext)_localctx, predIndex); } return true; } @@ -1186,49 +1878,82 @@ private boolean booleanTerm_sempred(BooleanTermContext _localctx, int predIndex) } public static final String _serializedATN = - "\3\uacf5\uee8c\u4f5d\u8b0d\u4a45\u78bd\u1b2f\u3378\3\25\u00a3\4\2\t\2"+ - "\4\3\t\3\4\4\t\4\4\5\t\5\4\6\t\6\4\7\t\7\4\b\t\b\4\t\t\t\4\n\t\n\4\13"+ - "\t\13\4\f\t\f\4\r\t\r\4\16\t\16\4\17\t\17\4\20\t\20\4\21\t\21\4\22\t\22"+ - "\4\23\t\23\4\24\t\24\4\25\t\25\4\26\t\26\4\27\t\27\4\30\t\30\3\2\3\2\3"+ - "\2\3\3\5\3\65\n\3\3\3\3\3\3\3\3\4\3\4\3\5\3\5\3\5\3\5\7\5@\n\5\f\5\16"+ - "\5C\13\5\5\5E\n\5\3\6\3\6\5\6I\n\6\3\7\3\7\3\7\3\b\3\b\3\t\3\t\3\t\3\t"+ - "\7\tT\n\t\f\t\16\tW\13\t\3\n\3\n\3\n\5\n\\\n\n\3\13\3\13\3\13\3\13\3\13"+ - "\5\13c\n\13\3\f\3\f\3\f\7\fh\n\f\f\f\16\fk\13\f\3\r\3\r\3\r\3\16\3\16"+ - "\3\17\3\17\3\17\3\17\3\17\3\17\7\17x\n\17\f\17\16\17{\13\17\3\20\3\20"+ - "\3\20\3\20\3\20\3\20\7\20\u0083\n\20\f\20\16\20\u0086\13\20\3\21\5\21"+ - "\u0089\n\21\3\21\3\21\3\22\3\22\3\22\5\22\u0090\n\22\3\22\5\22\u0093\n"+ - "\22\3\23\3\23\3\24\3\24\3\25\3\25\3\26\3\26\3\26\3\26\3\27\3\27\3\30\3"+ - "\30\3\30\2\31\2\4\6\b\n\f\16\20\22\24\26\30\32\34\36 \"$&(*,.\2\4\4\2"+ - "\4\4\7\7\4\2\17\20\23\23\u0098\2\60\3\2\2\2\4\64\3\2\2\2\69\3\2\2\2\b"+ - "D\3\2\2\2\nF\3\2\2\2\fJ\3\2\2\2\16M\3\2\2\2\20O\3\2\2\2\22X\3\2\2\2\24"+ - "]\3\2\2\2\26d\3\2\2\2\30l\3\2\2\2\32o\3\2\2\2\34q\3\2\2\2\36|\3\2\2\2"+ - " \u0088\3\2\2\2\"\u008c\3\2\2\2$\u0094\3\2\2\2&\u0096\3\2\2\2(\u0098\3"+ - "\2\2\2*\u009a\3\2\2\2,\u009e\3\2\2\2.\u00a0\3\2\2\2\60\61\7\22\2\2\61"+ - "\62\5\4\3\2\62\3\3\2\2\2\63\65\5\6\4\2\64\63\3\2\2\2\64\65\3\2\2\2\65"+ - "\66\3\2\2\2\66\67\5\b\5\2\678\5\16\b\28\5\3\2\2\29:\t\2\2\2:\7\3\2\2\2"+ - ";E\7\13\2\2\7\t\2\2>@\5\n\6\2?=\3\2\2\2@C\3\2\2\2A?\3\2\2"+ - "\2AB\3\2\2\2BE\3\2\2\2CA\3\2\2\2D;\3\2\2\2D<\3\2\2\2E\t\3\2\2\2FH\5,\27"+ - "\2GI\5\f\7\2HG\3\2\2\2HI\3\2\2\2I\13\3\2\2\2JK\7\3\2\2KL\5,\27\2L\r\3"+ - "\2\2\2MN\5\20\t\2N\17\3\2\2\2OP\7\16\2\2PU\5\22\n\2QR\7\t\2\2RT\5\22\n"+ - "\2SQ\3\2\2\2TW\3\2\2\2US\3\2\2\2UV\3\2\2\2V\21\3\2\2\2WU\3\2\2\2X[\5."+ - "\30\2YZ\7\3\2\2Z\\\5\24\13\2[Y\3\2\2\2[\\\3\2\2\2\\\23\3\2\2\2]b\5.\30"+ - "\2^_\7\r\2\2_`\5\26\f\2`a\7\b\2\2ac\3\2\2\2b^\3\2\2\2bc\3\2\2\2c\25\3"+ - "\2\2\2di\5,\27\2ef\7\t\2\2fh\5,\27\2ge\3\2\2\2hk\3\2\2\2ig\3\2\2\2ij\3"+ - "\2\2\2j\27\3\2\2\2ki\3\2\2\2lm\7\f\2\2mn\5\32\16\2n\31\3\2\2\2op\5\34"+ - "\17\2p\33\3\2\2\2qr\b\17\1\2rs\5\36\20\2sy\3\2\2\2tu\6\17\2\3uv\7\n\2"+ - "\2vx\5\36\20\2wt\3\2\2\2x{\3\2\2\2yw\3\2\2\2yz\3\2\2\2z\35\3\2\2\2{y\3"+ - "\2\2\2|}\b\20\1\2}~\5 \21\2~\u0084\3\2\2\2\177\u0080\6\20\3\3\u0080\u0081"+ - "\7\5\2\2\u0081\u0083\5 \21\2\u0082\177\3\2\2\2\u0083\u0086\3\2\2\2\u0084"+ - "\u0082\3\2\2\2\u0084\u0085\3\2\2\2\u0085\37\3\2\2\2\u0086\u0084\3\2\2"+ - "\2\u0087\u0089\7\21\2\2\u0088\u0087\3\2\2\2\u0088\u0089\3\2\2\2\u0089"+ - "\u008a\3\2\2\2\u008a\u008b\5\"\22\2\u008b!\3\2\2\2\u008c\u0092\5&\24\2"+ - "\u008d\u008f\7\6\2\2\u008e\u0090\7\21\2\2\u008f\u008e\3\2\2\2\u008f\u0090"+ - "\3\2\2\2\u0090\u0091\3\2\2\2\u0091\u0093\5$\23\2\u0092\u008d\3\2\2\2\u0092"+ - "\u0093\3\2\2\2\u0093#\3\2\2\2\u0094\u0095\t\3\2\2\u0095%\3\2\2\2\u0096"+ - "\u0097\5(\25\2\u0097\'\3\2\2\2\u0098\u0099\5*\26\2\u0099)\3\2\2\2\u009a"+ - "\u009b\7\r\2\2\u009b\u009c\5\34\17\2\u009c\u009d\7\b\2\2\u009d+\3\2\2"+ - "\2\u009e\u009f\7\24\2\2\u009f-\3\2\2\2\u00a0\u00a1\7\24\2\2\u00a1/\3\2"+ - "\2\2\17\64ADHU[biy\u0084\u0088\u008f\u0092"; + "\3\uacf5\uee8c\u4f5d\u8b0d\u4a45\u78bd\u1b2f\u3378\3!\u00fe\4\2\t\2\4"+ + "\3\t\3\4\4\t\4\4\5\t\5\4\6\t\6\4\7\t\7\4\b\t\b\4\t\t\t\4\n\t\n\4\13\t"+ + "\13\4\f\t\f\4\r\t\r\4\16\t\16\4\17\t\17\4\20\t\20\4\21\t\21\4\22\t\22"+ + "\4\23\t\23\4\24\t\24\4\25\t\25\4\26\t\26\4\27\t\27\4\30\t\30\4\31\t\31"+ + "\4\32\t\32\4\33\t\33\4\34\t\34\4\35\t\35\4\36\t\36\4\37\t\37\4 \t \4!"+ + "\t!\4\"\t\"\4#\t#\4$\t$\4%\t%\4&\t&\3\2\3\2\3\2\3\3\5\3Q\n\3\3\3\3\3\3"+ + "\3\5\3V\n\3\3\4\3\4\3\5\3\5\3\5\3\5\7\5^\n\5\f\5\16\5a\13\5\5\5c\n\5\3"+ + "\6\3\6\5\6g\n\6\3\7\3\7\3\7\3\7\3\b\3\b\5\bo\n\b\3\t\3\t\3\t\3\n\3\n\3"+ + "\13\3\13\3\13\3\13\7\13z\n\13\f\13\16\13}\13\13\3\f\3\f\3\f\5\f\u0082"+ + "\n\f\3\r\3\r\3\r\3\r\3\r\5\r\u0089\n\r\3\16\3\16\3\16\7\16\u008e\n\16"+ + "\f\16\16\16\u0091\13\16\3\17\3\17\3\17\3\20\3\20\3\21\3\21\3\21\3\21\3"+ + "\21\3\21\7\21\u009e\n\21\f\21\16\21\u00a1\13\21\3\22\3\22\3\22\3\22\3"+ + "\22\3\22\7\22\u00a9\n\22\f\22\16\22\u00ac\13\22\3\23\5\23\u00af\n\23\3"+ + "\23\3\23\3\24\3\24\3\24\5\24\u00b6\n\24\3\24\5\24\u00b9\n\24\3\25\3\25"+ + "\3\26\3\26\3\27\3\27\3\30\3\30\3\30\3\30\3\31\3\31\3\32\3\32\3\32\3\32"+ + "\5\32\u00cb\n\32\3\33\3\33\3\33\3\34\3\34\3\34\3\34\3\34\3\35\3\35\3\35"+ + "\3\35\3\35\3\36\3\36\3\36\3\37\3\37\3\37\5\37\u00e0\n\37\5\37\u00e2\n"+ + "\37\3 \3 \3!\3!\5!\u00e8\n!\3\"\3\"\3\"\3#\3#\3#\3#\3#\3$\3$\3$\7$\u00f5"+ + "\n$\f$\16$\u00f8\13$\3%\3%\3&\3&\3&\2\'\2\4\6\b\n\f\16\20\22\24\26\30"+ + "\32\34\36 \"$&(*,.\60\62\64\668:<>@BDFHJ\2\5\3\2\4\5\5\2\16\16\21\21\31"+ + "\31\5\2\7\7\f\f\30\30\u00ee\2L\3\2\2\2\4P\3\2\2\2\6W\3\2\2\2\bb\3\2\2"+ + "\2\nf\3\2\2\2\fh\3\2\2\2\16l\3\2\2\2\20p\3\2\2\2\22s\3\2\2\2\24u\3\2\2"+ + "\2\26~\3\2\2\2\30\u0083\3\2\2\2\32\u008a\3\2\2\2\34\u0092\3\2\2\2\36\u0095"+ + "\3\2\2\2 \u0097\3\2\2\2\"\u00a2\3\2\2\2$\u00ae\3\2\2\2&\u00b2\3\2\2\2"+ + "(\u00ba\3\2\2\2*\u00bc\3\2\2\2,\u00be\3\2\2\2.\u00c0\3\2\2\2\60\u00c4"+ + "\3\2\2\2\62\u00ca\3\2\2\2\64\u00cc\3\2\2\2\66\u00cf\3\2\2\28\u00d4\3\2"+ + "\2\2:\u00d9\3\2\2\2<\u00e1\3\2\2\2>\u00e3\3\2\2\2@\u00e7\3\2\2\2B\u00e9"+ + "\3\2\2\2D\u00ec\3\2\2\2F\u00f1\3\2\2\2H\u00f9\3\2\2\2J\u00fb\3\2\2\2L"+ + "M\7\37\2\2MN\5\4\3\2N\3\3\2\2\2OQ\5\6\4\2PO\3\2\2\2PQ\3\2\2\2QR\3\2\2"+ + "\2RS\5\b\5\2SU\5\22\n\2TV\5\60\31\2UT\3\2\2\2UV\3\2\2\2V\5\3\2\2\2WX\t"+ + "\2\2\2X\7\3\2\2\2Yc\7\b\2\2Z_\5\n\6\2[\\\7\6\2\2\\^\5\n\6\2][\3\2\2\2"+ + "^a\3\2\2\2_]\3\2\2\2_`\3\2\2\2`c\3\2\2\2a_\3\2\2\2bY\3\2\2\2bZ\3\2\2\2"+ + "c\t\3\2\2\2dg\5\f\7\2eg\5\16\b\2fd\3\2\2\2fe\3\2\2\2g\13\3\2\2\2hi\5J"+ + "&\2ij\7\26\2\2jk\5H%\2k\r\3\2\2\2ln\5H%\2mo\5\20\t\2nm\3\2\2\2no\3\2\2"+ + "\2o\17\3\2\2\2pq\7\13\2\2qr\5H%\2r\21\3\2\2\2st\5\24\13\2t\23\3\2\2\2"+ + "uv\7\35\2\2v{\5\26\f\2wx\7\6\2\2xz\5\26\f\2yw\3\2\2\2z}\3\2\2\2{y\3\2"+ + "\2\2{|\3\2\2\2|\25\3\2\2\2}{\3\2\2\2~\u0081\5J&\2\177\u0080\7\13\2\2\u0080"+ + "\u0082\5\30\r\2\u0081\177\3\2\2\2\u0081\u0082\3\2\2\2\u0082\27\3\2\2\2"+ + "\u0083\u0088\5J&\2\u0084\u0085\7\n\2\2\u0085\u0086\5\32\16\2\u0086\u0087"+ + "\7\27\2\2\u0087\u0089\3\2\2\2\u0088\u0084\3\2\2\2\u0088\u0089\3\2\2\2"+ + "\u0089\31\3\2\2\2\u008a\u008f\5H%\2\u008b\u008c\7\6\2\2\u008c\u008e\5"+ + "H%\2\u008d\u008b\3\2\2\2\u008e\u0091\3\2\2\2\u008f\u008d\3\2\2\2\u008f"+ + "\u0090\3\2\2\2\u0090\33\3\2\2\2\u0091\u008f\3\2\2\2\u0092\u0093\7\t\2"+ + "\2\u0093\u0094\5\36\20\2\u0094\35\3\2\2\2\u0095\u0096\5 \21\2\u0096\37"+ + "\3\2\2\2\u0097\u0098\b\21\1\2\u0098\u0099\5\"\22\2\u0099\u009f\3\2\2\2"+ + "\u009a\u009b\6\21\2\3\u009b\u009c\7\r\2\2\u009c\u009e\5\"\22\2\u009d\u009a"+ + "\3\2\2\2\u009e\u00a1\3\2\2\2\u009f\u009d\3\2\2\2\u009f\u00a0\3\2\2\2\u00a0"+ + "!\3\2\2\2\u00a1\u009f\3\2\2\2\u00a2\u00a3\b\22\1\2\u00a3\u00a4\5$\23\2"+ + "\u00a4\u00aa\3\2\2\2\u00a5\u00a6\6\22\3\3\u00a6\u00a7\7\22\2\2\u00a7\u00a9"+ + "\5$\23\2\u00a8\u00a5\3\2\2\2\u00a9\u00ac\3\2\2\2\u00aa\u00a8\3\2\2\2\u00aa"+ + "\u00ab\3\2\2\2\u00ab#\3\2\2\2\u00ac\u00aa\3\2\2\2\u00ad\u00af\7\36\2\2"+ + "\u00ae\u00ad\3\2\2\2\u00ae\u00af\3\2\2\2\u00af\u00b0\3\2\2\2\u00b0\u00b1"+ + "\5&\24\2\u00b1%\3\2\2\2\u00b2\u00b8\5*\26\2\u00b3\u00b5\7\33\2\2\u00b4"+ + "\u00b6\7\36\2\2\u00b5\u00b4\3\2\2\2\u00b5\u00b6\3\2\2\2\u00b6\u00b7\3"+ + "\2\2\2\u00b7\u00b9\5(\25\2\u00b8\u00b3\3\2\2\2\u00b8\u00b9\3\2\2\2\u00b9"+ + "\'\3\2\2\2\u00ba\u00bb\t\3\2\2\u00bb)\3\2\2\2\u00bc\u00bd\5,\27\2\u00bd"+ + "+\3\2\2\2\u00be\u00bf\5.\30\2\u00bf-\3\2\2\2\u00c0\u00c1\7\n\2\2\u00c1"+ + "\u00c2\5 \21\2\u00c2\u00c3\7\27\2\2\u00c3/\3\2\2\2\u00c4\u00c5\5\62\32"+ + "\2\u00c5\61\3\2\2\2\u00c6\u00cb\5\64\33\2\u00c7\u00cb\5\66\34\2\u00c8"+ + "\u00cb\58\35\2\u00c9\u00cb\5:\36\2\u00ca\u00c6\3\2\2\2\u00ca\u00c7\3\2"+ + "\2\2\u00ca\u00c8\3\2\2\2\u00ca\u00c9\3\2\2\2\u00cb\63\3\2\2\2\u00cc\u00cd"+ + "\7\3\2\2\u00cd\u00ce\5J&\2\u00ce\65\3\2\2\2\u00cf\u00d0\5<\37\2\u00d0"+ + "\u00d1\7\17\2\2\u00d1\u00d2\5J&\2\u00d2\u00d3\5@!\2\u00d3\67\3\2\2\2\u00d4"+ + "\u00d5\7\25\2\2\u00d5\u00d6\5<\37\2\u00d6\u00d7\7\17\2\2\u00d7\u00d8\5"+ + "J&\2\u00d89\3\2\2\2\u00d9\u00da\7\20\2\2\u00da\u00db\5J&\2\u00db;\3\2"+ + "\2\2\u00dc\u00e2\7\24\2\2\u00dd\u00df\5> \2\u00de\u00e0\7\34\2\2\u00df"+ + "\u00de\3\2\2\2\u00df\u00e0\3\2\2\2\u00e0\u00e2\3\2\2\2\u00e1\u00dc\3\2"+ + "\2\2\u00e1\u00dd\3\2\2\2\u00e2=\3\2\2\2\u00e3\u00e4\t\4\2\2\u00e4?\3\2"+ + "\2\2\u00e5\u00e8\5B\"\2\u00e6\u00e8\5D#\2\u00e7\u00e5\3\2\2\2\u00e7\u00e6"+ + "\3\2\2\2\u00e8A\3\2\2\2\u00e9\u00ea\7\32\2\2\u00ea\u00eb\5\36\20\2\u00eb"+ + "C\3\2\2\2\u00ec\u00ed\7\23\2\2\u00ed\u00ee\7\n\2\2\u00ee\u00ef\5F$\2\u00ef"+ + "\u00f0\7\27\2\2\u00f0E\3\2\2\2\u00f1\u00f6\5H%\2\u00f2\u00f3\7\6\2\2\u00f3"+ + "\u00f5\5H%\2\u00f4\u00f2\3\2\2\2\u00f5\u00f8\3\2\2\2\u00f6\u00f4\3\2\2"+ + "\2\u00f6\u00f7\3\2\2\2\u00f7G\3\2\2\2\u00f8\u00f6\3\2\2\2\u00f9\u00fa"+ + "\7 \2\2\u00faI\3\2\2\2\u00fb\u00fc\7 \2\2\u00fcK\3\2\2\2\26PU_bfn{\u0081"+ + "\u0088\u008f\u009f\u00aa\u00ae\u00b5\u00b8\u00ca\u00df\u00e1\u00e7\u00f6"; public static final ATN _ATN = ATNSimulator.deserialize(_serializedATN.toCharArray()); static { diff --git a/src/com/etk/parser/SelectObject.java b/src/com/etk/parser/SelectObject.java index efe17fd..042185c 100644 --- a/src/com/etk/parser/SelectObject.java +++ b/src/com/etk/parser/SelectObject.java @@ -10,22 +10,34 @@ * To change this template use File | Settings | File Templates. */ public class SelectObject implements ParserInterface { - ArrayList columnNames; - ArrayList tableNames; + private ArrayList noPrefColNames; + private ArrayList prefColNames; + private ArrayList tableNames; public SelectObject(){ } - public void addColumnName(String columnName){ - if(columnNames == null){ - columnNames = new ArrayList(); + public void addFreeColumnName(String noPrefColName){ + if(noPrefColNames == null){ + noPrefColNames = new ArrayList(); } - this.columnNames.add(columnName); + this.noPrefColNames.add(noPrefColName); } - public ArrayList getColumnNames(){ - return this.columnNames; + public ArrayList getNoPrefColNames(){ + return this.noPrefColNames; + } + + public void addPrefColNames(ProjectionCell prefColName) { + if(prefColNames == null){ + prefColNames = new ArrayList(); + } + this.prefColNames.add(prefColName); + } + + public ArrayList getPrefColNames() { + return prefColNames; } public void addTableName(String tableName){ diff --git a/src/com/etk/parser/SelectQueryToObject.java b/src/com/etk/parser/SelectQueryToObject.java index 3aa561e..fffbc85 100644 --- a/src/com/etk/parser/SelectQueryToObject.java +++ b/src/com/etk/parser/SelectQueryToObject.java @@ -38,14 +38,14 @@ public SelectQueryToObject(InputStream parseString) throws Exception { } } - public void exitDerivedColumn(@NotNull SELECTParser.DerivedColumnContext ctx) { - selectObject.addColumnName(ctx.columnName().getText()); + /*public void exitDerivedColumn(@NotNull SELECTParser.DerivedColumnContext ctx) { + selectObject.addFreeColumnName(ctx.columnName().getText()); } public void enterTablePrimary(@NotNull SELECTParser.TablePrimaryContext ctx) { selectObject.addTableName(ctx.tableName().getText()); } - + */ public SelectObject getSelectObject(){ return this.selectObject; } diff --git a/src/com/etk/parser/test.txt b/src/com/etk/parser/test.txt new file mode 100644 index 0000000..92bb71c --- /dev/null +++ b/src/com/etk/parser/test.txt @@ -0,0 +1 @@ +SELECT a FROM b , c INNER JOIN z USING (a, b, c) \ No newline at end of file From 9c19cdc38236f8ddeaa23d5108fcccbd6b1b3739 Mon Sep 17 00:00:00 2001 From: Georgy Shabunin Date: Sun, 8 Dec 2013 22:52:46 +0100 Subject: [PATCH 19/37] "Add getters to ProjectionCell" --- src/com/etk/parser/ProjectionCell.java | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/com/etk/parser/ProjectionCell.java b/src/com/etk/parser/ProjectionCell.java index da8291f..0a4e1d3 100644 --- a/src/com/etk/parser/ProjectionCell.java +++ b/src/com/etk/parser/ProjectionCell.java @@ -15,4 +15,13 @@ public ProjectionCell(String prefix, String columnName){ this.prefix = prefix; this.columnName = columnName; } + + public String getPrefix() { + return prefix; + } + + public String getColumnName() { + return columnName; + } + } From 152a5e2dd9ec5d09ed2b5fef60525817bca7a7e3 Mon Sep 17 00:00:00 2001 From: Georgy Shabunin Date: Sun, 8 Dec 2013 23:25:44 +0100 Subject: [PATCH 20/37] "Able to fill ProjectionCell with data" --- src/com/etk/network/client/Client.java | 2 +- src/com/etk/network/server/SessionHandler.java | 13 ++++++++++--- src/com/etk/parser/SelectQueryToObject.java | 9 ++++++++- 3 files changed, 19 insertions(+), 5 deletions(-) diff --git a/src/com/etk/network/client/Client.java b/src/com/etk/network/client/Client.java index d148588..3d6bd56 100644 --- a/src/com/etk/network/client/Client.java +++ b/src/com/etk/network/client/Client.java @@ -79,7 +79,7 @@ private void query(Connection conn, ArrayList list, String query) { try { Statement st = conn.createStatement(); // the syntax for FROM is schema.table - ResultSet rs = st.executeQuery("SELECT a FROM b, c INNER JOIN z USING (a, b, c)"); + ResultSet rs = st.executeQuery("SELECT a.d, a.c, b.d FROM a, b"); while (rs.next()) { String name = rs.getString("name"); System.out.println(name); diff --git a/src/com/etk/network/server/SessionHandler.java b/src/com/etk/network/server/SessionHandler.java index 129a521..e022365 100644 --- a/src/com/etk/network/server/SessionHandler.java +++ b/src/com/etk/network/server/SessionHandler.java @@ -5,6 +5,7 @@ import java.nio.ByteBuffer; import java.util.Arrays; +import com.etk.parser.ProjectionCell; import com.etk.parser.SelectObject; import com.etk.parser.SelectQueryToObject; @@ -183,15 +184,21 @@ public void run() { SelectQueryToObject selectQueryToObject = new SelectQueryToObject(is); SelectObject selectObject = selectQueryToObject.getSelectObject(); + //just for understanding of how to use selectObject: -/* for(String columnName : selectObject.getNoPrefColNames()){ - System.out.println("Column: " + columnName); + /* for(String noPrefColName : selectObject.getNoPrefColNames()){ + System.out.println("Column: " + noPrefColName); + } + */ + for(ProjectionCell prefColName : selectObject.getPrefColNames()){ + System.out.println("Prefixed column found \n prefix: " + prefColName.getPrefix() + + "\n column name: " + prefColName.getColumnName()); } for(String tableName : selectObject.getTableNames()){ System.out.println("Table: " + tableName); } -*/ + /* * this is in case the server receive an empty query string and * seems to work sendEmptyQueryResponseMessage(dataOutputStream); diff --git a/src/com/etk/parser/SelectQueryToObject.java b/src/com/etk/parser/SelectQueryToObject.java index fffbc85..94908c6 100644 --- a/src/com/etk/parser/SelectQueryToObject.java +++ b/src/com/etk/parser/SelectQueryToObject.java @@ -38,7 +38,14 @@ public SelectQueryToObject(InputStream parseString) throws Exception { } } - /*public void exitDerivedColumn(@NotNull SELECTParser.DerivedColumnContext ctx) { + + @Override public void exitColumnInTable(@NotNull SELECTParser.ColumnInTableContext ctx) { + String tableName = ctx.tableName().getText(); + String columnName = ctx.columnName().getText(); + ProjectionCell projectionCell = new ProjectionCell(tableName, columnName); + selectObject.addPrefColNames(projectionCell); + } + /* public void exitDerivedColumn(@NotNull SELECTParser.DerivedColumnContext ctx) { selectObject.addFreeColumnName(ctx.columnName().getText()); } From c568e44e9897574b59cb1f5a2f1b19a7889a2948 Mon Sep 17 00:00:00 2001 From: w-is-h Date: Wed, 11 Dec 2013 15:50:17 +0100 Subject: [PATCH 21/37] New approach in semanticLayer Started implementing tree structure. --- src/com/etk/data/DataSource.java | 6 +- .../etk/data/RemoteSourceHierarchyRDF.java | 279 ++++++++++++++++++ src/com/etk/data/RemoteSourceRDF.java | 7 + 3 files changed, 289 insertions(+), 3 deletions(-) create mode 100644 src/com/etk/data/RemoteSourceHierarchyRDF.java diff --git a/src/com/etk/data/DataSource.java b/src/com/etk/data/DataSource.java index 9369e1d..142eeb7 100644 --- a/src/com/etk/data/DataSource.java +++ b/src/com/etk/data/DataSource.java @@ -16,9 +16,9 @@ */ public interface DataSource { - public List getEntityCandidates(int limit, int offset, boolean label); - public List getAttributes(String entity, int limit, int offset, boolean label); + public List getEntityCandidates(Properties queryProperties); + public List getAttributes(String entity, Properties queryProperties); public List getType(String entity, String attribute); - public List getValues(String entity, String attributes[], int limit, int offset); + public List getValues(String entity, String attributes[], Properties queryProperties); public List getAvailableEndpoints(); } diff --git a/src/com/etk/data/RemoteSourceHierarchyRDF.java b/src/com/etk/data/RemoteSourceHierarchyRDF.java new file mode 100644 index 0000000..58b4a23 --- /dev/null +++ b/src/com/etk/data/RemoteSourceHierarchyRDF.java @@ -0,0 +1,279 @@ +package com.etk.data; + +import java.util.ArrayList; +import java.util.List; + +import com.hp.hpl.jena.query.Query; +import com.hp.hpl.jena.query.QueryExecution; +import com.hp.hpl.jena.query.QueryExecutionFactory; +import com.hp.hpl.jena.query.QueryFactory; +import com.hp.hpl.jena.query.QuerySolution; +import com.hp.hpl.jena.query.ResultSet; +import com.hp.hpl.jena.rdf.model.RDFNode; + +public class RemoteSourceHierarchyRDF implements DataSource{ + String service; + String queryStringTemplate; + String defaultDataSetName; + + public RemoteSourceHierarchyRDF( String service, String defaultDataSetName ){ + this.service = service; + this.defaultDataSetName = defaultDataSetName; + queryStringTemplate = "PREFIX rdf: " + + "PREFIX rdfs: "; + } + + @Override + public List getEntityCandidates(int limit, int offset, boolean label) { + String queryString = queryStringTemplate; + queryString += "SELECT DISTINCT (count(?o) as ?num) ?o FROM <" + defaultDataSetName + "> " + + "WHERE { ?s rdfs:subClassOf ?o. " + + "FILTER NOT EXISTS { ?o rdfs:subClassOf ?o2 }. "; + + // Checks should the sparql query ask for a rdfs:label + // This should be used only if you are sure that there is a predicate + // rdfs:label in the data source + if( label ){ + queryString += "?o rdfs:label ?label. " + + "FILTER (lang(?label) = 'en' || lang(?label) = '') "; + } + + queryString += "}"; + /* For now I will disable order by, because it is very slow + if( limit != 0 && offset != 0 ){ + queryString += " ORDER BY ?o"; + } + */ + + //Add order by and sort by + queryString += " GROUP BY ?o ORDER BY DESC(?num)"; + + if( limit != 0 ){ + queryString += " LIMIT " + Integer.toString( limit ); + } + if( offset != 0 ){ + queryString += " OFFSET " + Integer.toString( offset ); + } + System.out.println(queryString); + Query query = QueryFactory.create(queryString); + QueryExecution queryExecution = QueryExecutionFactory.createServiceRequest( + service, query ); + ResultSet resultSet = queryExecution.execSelect(); + + return entityCandidatesFromRS(resultSet, label); + } + + private List entityCandidatesFromRS(ResultSet resultSet, boolean label){ + List entityCandidates = new ArrayList(); + + QuerySolution qs; + if( label ){ + while( resultSet.hasNext() ){ + qs = resultSet.next(); + entityCandidates.add( new EntityCandidate(qs.get("o").toString(), qs.get("label").toString()) ); + } + } + else{ + while( resultSet.hasNext() ){ + qs = resultSet.next(); + entityCandidates.add( new EntityCandidate(qs.get("o").toString()) ); + } + } + + + + return entityCandidates; + } + + @Override + public List getAttributes(String entity, int limit, int offset, boolean label){ + String queryString = queryStringTemplate; + queryString += "Select (count(?p) as ?num) ?p WHERE { ?s rdf:type/rdfs:subClassOf* <" + entity + ">." + + " ?s ?p ?o." + + "FILTER ( regex(str(?p), 'http://dbpedia.org/property')). "; + + /*This doesn't work for some reason + * " ?p a rdf:Property. " + + */ + // Checks should the sparql query ask for a rdfs:label + // This should be used only if you are sure that there is a predicate + // rdfs:label in the data source + if( label ){ + queryString += "?p rdfs:label ?label. " + + "FILTER (lang(?label) = 'en' || lang(?label) = '') "; + } + + queryString += "}"; + /* For now I will disable order by, because it is very slow + if( limit != 0 && offset != 0 ){ + queryString += " ORDER BY ?o"; + } + */ + + //Add group by and order by + queryString += "group by ?p order by desc(?num) "; + + if( limit != 0 ){ + queryString += " LIMIT " + Integer.toString( limit ); + } + if( offset != 0 ){ + queryString += " OFFSET " + Integer.toString( offset ); + } + System.out.println(queryString); + Query query = QueryFactory.create(queryString); + QueryExecution queryExecution = QueryExecutionFactory.createServiceRequest( + service, query ); + ResultSet resultSet = queryExecution.execSelect(); + + return atributesFromRS(resultSet, label); + } + + private List atributesFromRS(ResultSet resultSet, boolean label){ + List atributeCandidates = new ArrayList(); + + QuerySolution qs; + if( label ){ + while( resultSet.hasNext() ){ + qs = resultSet.next(); + atributeCandidates.add( new AttributeCandidate(qs.get("p").toString(), qs.get("label").toString()) ); + } + } + else{ + while( resultSet.hasNext() ){ + qs = resultSet.next(); + + atributeCandidates.add( new AttributeCandidate(qs.get("p").toString()) ); + } + } + + + + return atributeCandidates; + } + + @Override + public List getType(String entity, String attribute) { + // TODO Auto-generated method stub + return null; + } + + @Override + public List getValues(String entity, String attributes[], int limit, int offset) { + String queryString = queryStringTemplate; + queryString += "Select distinct ?s " + repeateString("?o", attributes.length) + + " WHERE { ?s rdf:type/rdfs:subClassOf* <" + entity + ">."; + + for(int i = 0; i < attributes.length; i++){ + queryString += "?s" + " <" + attributes[i] + "> " + "?o" + i + "."; + } + + + queryString += "}"; + /* For now I will disable order by, because it is very slow + if( limit != 0 && offset != 0 ){ + queryString += " ORDER BY ?o "; + } + */ + + + if( limit != 0 ){ + queryString += " LIMIT " + Integer.toString( limit ); + } + if( offset != 0 ){ + queryString += " OFFSET " + Integer.toString( offset ); + } + Query query = QueryFactory.create(queryString); + QueryExecution queryExecution = QueryExecutionFactory.createServiceRequest( + service, query ); + ResultSet resultSet = queryExecution.execSelect(); + + return valuesFromRS(resultSet, attributes); + } + + private List valuesFromRS(ResultSet resultSet, String attributes[] ){ + List valueCandidates = new ArrayList(); + int numOfAttributes = attributes.length; + + QuerySolution qs; + ValueCandidate valueCandidate; + RDFNode node; + String resourceName; + while( resultSet.hasNext() ){ + qs = resultSet.next(); + valueCandidate = new ValueCandidate(qs.get("s").toString()); + + for(int i = 0; i < numOfAttributes; i++){ + node = qs.get(String.format("?o%d", i)); + + if( node.isResource() ){ + resourceName = node.asResource().getURI(); + valueCandidate.addOneValue( + resourceName.substring(resourceName.lastIndexOf("/") + 1), + attributes[i]); + } + else{ + valueCandidate.addOneValue(node.toString(), attributes[i]); + } + } + valueCandidates.add(valueCandidate); + } + + + return valueCandidates; + } + + private String repeateString(String s, int n){ + String out = " "; + + for(int i = 0; i < n; i++){ + out += s + i + " "; + } + + return out; + } + + public List getAvailableEndpoints(){ + return null; + } + + @Override + public List getEntityCandidates(String superClass, int limit, + int offset, boolean label) { + String queryString = queryStringTemplate; + queryString += "SELECT DISTINCT (count(?o) as ?num) ?o FROM <" + defaultDataSetName + "> " + + "WHERE { ?s rdfs:subClassOf ?o. " + + "FILTER NOT EXISTS { ?o rdfs:subClassOf ?o2 }. "; + + // Checks should the sparql query ask for a rdfs:label + // This should be used only if you are sure that there is a predicate + // rdfs:label in the data source + if( label ){ + queryString += "?o rdfs:label ?label. " + + "FILTER (lang(?label) = 'en' || lang(?label) = '') "; + } + + queryString += "}"; + /* For now I will disable order by, because it is very slow + if( limit != 0 && offset != 0 ){ + queryString += " ORDER BY ?o"; + } + */ + + //Add order by and sort by + queryString += " GROUP BY ?o ORDER BY DESC(?num)"; + + if( limit != 0 ){ + queryString += " LIMIT " + Integer.toString( limit ); + } + if( offset != 0 ){ + queryString += " OFFSET " + Integer.toString( offset ); + } + System.out.println(queryString); + Query query = QueryFactory.create(queryString); + QueryExecution queryExecution = QueryExecutionFactory.createServiceRequest( + service, query ); + ResultSet resultSet = queryExecution.execSelect(); + + return entityCandidatesFromRS(resultSet, label); + } +} diff --git a/src/com/etk/data/RemoteSourceRDF.java b/src/com/etk/data/RemoteSourceRDF.java index e2e5f77..71697a7 100644 --- a/src/com/etk/data/RemoteSourceRDF.java +++ b/src/com/etk/data/RemoteSourceRDF.java @@ -235,4 +235,11 @@ private String repeateString(String s, int n){ public List getAvailableEndpoints(){ return null; } + + @Override + public List getEntityCandidates(String superClass, int limit, + int offset, boolean label) { + // TODO Auto-generated method stub + return null; + } } From 2616c4f3738d99fbcead5791bef84c559095da62 Mon Sep 17 00:00:00 2001 From: Mladen Subotic Date: Wed, 11 Dec 2013 17:38:39 +0100 Subject: [PATCH 22/37] midwork --- src/com/etk/db/QueryExecutorImpl.java | 37 ++++++++++++++++++++++++--- 1 file changed, 33 insertions(+), 4 deletions(-) diff --git a/src/com/etk/db/QueryExecutorImpl.java b/src/com/etk/db/QueryExecutorImpl.java index d84ab3a..73f73f6 100644 --- a/src/com/etk/db/QueryExecutorImpl.java +++ b/src/com/etk/db/QueryExecutorImpl.java @@ -10,6 +10,8 @@ import com.etk.data.ValueCandidate; import com.etk.data.query.Properties; import com.etk.db.exceptions.RelsemDBException; +import com.etk.db.model.RowCollection; +import com.etk.db.model.Table; import com.etk.db.query.QueryResult; import com.etk.manager.schema.Attribute; import com.etk.manager.schema.Schema; @@ -38,11 +40,25 @@ public List executeQuery(SelectObject sqlQuery) //create a map requested tables List reqTables = sqlQuery.getTableNames(); - //fill reqProjection + //liste attributa za danu tablicu + Map> reqProjection = new HashMap>(); - Map> reqProjection = null; Map> tableSelects = new HashMap<>(); //valueCandidates for table and projection + + //fill reqProjection + //for each requested table, load all domain attributes and fill into reqProject + for(String rTable : reqTables) { + UserTable t = schema.getTable(rTable); + Map tAttributes = t.getAttributes(); + reqProjection.put(t.getTableName(), new ArrayList()); + for(String aName : tAttributes.keySet()) { + Attribute a = tAttributes.get(aName); + reqProjection.get(t.getTableName()).add(a); + } + } + + for(String table : reqProjection.keySet()) { List reqAttributes = reqProjection.get(table); @@ -58,7 +74,20 @@ public List executeQuery(SelectObject sqlQuery) } //convert lists of valueCandidates to rowCollections and join + Map dataCollections = new HashMap(); + for(String table : tableSelects.keySet()) { + RowCollection rc ; + + List valueCandidates = tableSelects.get(table); + for(Object vC : valueCandidates) { + ValueCandidate val = (ValueCandidate) vC; + //val is a map with attribute uris as keys + //create rows with attributes ordered as in domaintTable + + + } + } @@ -78,8 +107,8 @@ public boolean validateQuery(SelectObject sqlQuery) { } //TODO fix vaidation based on tables of requested attributes - for(String qAttr : sqlQuery.getColumnNames()) { - } +// for(String qAttr : sqlQuery.getColumnNames()) { +// } From 942608b6e08f16b441775c01d2ff7d03da05662a Mon Sep 17 00:00:00 2001 From: w-is-h Date: Sun, 15 Dec 2013 06:18:35 +0100 Subject: [PATCH 23/37] New implementation of sparql queries It's late, no idea what to write... --- src/com/etk/data/DataSource.java | 7 +- .../etk/data/RemoteSourceHierarchyRDF.java | 275 +++++++++--------- src/com/etk/data/TestRemoteSourceRDF.java | 86 +++--- src/com/etk/data/query/OperatorMapping.java | 25 ++ src/com/etk/data/query/Properties.java | 42 ++- src/com/etk/data/query/SelectionClause.java | 8 + 6 files changed, 254 insertions(+), 189 deletions(-) create mode 100644 src/com/etk/data/query/OperatorMapping.java diff --git a/src/com/etk/data/DataSource.java b/src/com/etk/data/DataSource.java index c45f446..93f18c4 100644 --- a/src/com/etk/data/DataSource.java +++ b/src/com/etk/data/DataSource.java @@ -1,5 +1,7 @@ package com.etk.data; +import com.etk.data.query.Expression; +import com.etk.data.query.Properties; import com.etk.manager.schema.Attribute; import com.etk.manager.schema.Type; import com.etk.manager.schema.mappings.AttributeMapping; @@ -15,10 +17,9 @@ * To change this template use File | Settings | File Templates. */ public interface DataSource { - public List getEntityCandidates(Properties queryProperties); public List getAttributes(String entity, Properties queryProperties); - public List getType(String entity, String attribute); - public List getValues(String entity, String attributes[], Properties queryProperties); + public String getType(String entity, String attribute); + public List getValues(String entity, String attributes[], Properties queryProperties, Expression whereExpression); public List getAvailableEndpoints(); } diff --git a/src/com/etk/data/RemoteSourceHierarchyRDF.java b/src/com/etk/data/RemoteSourceHierarchyRDF.java index 58b4a23..0465b0b 100644 --- a/src/com/etk/data/RemoteSourceHierarchyRDF.java +++ b/src/com/etk/data/RemoteSourceHierarchyRDF.java @@ -3,13 +3,22 @@ import java.util.ArrayList; import java.util.List; +import sun.misc.Regexp; + +import com.etk.data.query.Expression; +import com.etk.data.query.Operator; +import com.etk.data.query.OperatorMapping; +import com.etk.data.query.Properties; +import com.etk.data.query.SelectionClause; import com.hp.hpl.jena.query.Query; import com.hp.hpl.jena.query.QueryExecution; import com.hp.hpl.jena.query.QueryExecutionFactory; import com.hp.hpl.jena.query.QueryFactory; import com.hp.hpl.jena.query.QuerySolution; import com.hp.hpl.jena.query.ResultSet; +import com.hp.hpl.jena.query.Syntax; import com.hp.hpl.jena.rdf.model.RDFNode; +import com.hp.hpl.jena.reasoner.rulesys.builtins.Regex; public class RemoteSourceHierarchyRDF implements DataSource{ String service; @@ -20,145 +29,129 @@ public RemoteSourceHierarchyRDF( String service, String defaultDataSetName ){ this.service = service; this.defaultDataSetName = defaultDataSetName; queryStringTemplate = "PREFIX rdf: " + - "PREFIX rdfs: "; + "PREFIX rdfs: " + + "PREFIX xsd: " + + "PREFIX fn: "; } + @Override - public List getEntityCandidates(int limit, int offset, boolean label) { + public List getEntityCandidates(Properties queryProperties) { String queryString = queryStringTemplate; queryString += "SELECT DISTINCT (count(?o) as ?num) ?o FROM <" + defaultDataSetName + "> " + - "WHERE { ?s rdfs:subClassOf ?o. " + - "FILTER NOT EXISTS { ?o rdfs:subClassOf ?o2 }. "; - - // Checks should the sparql query ask for a rdfs:label - // This should be used only if you are sure that there is a predicate - // rdfs:label in the data source - if( label ){ - queryString += "?o rdfs:label ?label. " + - "FILTER (lang(?label) = 'en' || lang(?label) = '') "; - } + "WHERE { "; - queryString += "}"; - /* For now I will disable order by, because it is very slow - if( limit != 0 && offset != 0 ){ - queryString += " ORDER BY ?o"; - } - */ + if( queryProperties.getEntitySuperClass() != null ){ + queryString += "?o rdfs:subClassOf{" + queryProperties.getDepthFrom() + "," + + queryProperties.getDepthTo() + "} " + + "<" + queryProperties.getEntitySuperClass() + ">. }"; + } + else{ + queryString += "?s rdfs:subClassOf ?o. " + + "FILTER NOT EXISTS { ?o rdfs:subClassOf ?o2 }. }"; + } //Add order by and sort by queryString += " GROUP BY ?o ORDER BY DESC(?num)"; - if( limit != 0 ){ - queryString += " LIMIT " + Integer.toString( limit ); + if( queryProperties.getLimit() != 0 ){ + queryString += " LIMIT " + Integer.toString( queryProperties.getLimit() ); } - if( offset != 0 ){ - queryString += " OFFSET " + Integer.toString( offset ); + if( queryProperties.getOffset() != 0 ){ + queryString += " OFFSET " + Integer.toString( queryProperties.getOffset() ); } - System.out.println(queryString); - Query query = QueryFactory.create(queryString); + + Query query = QueryFactory.create(queryString, Syntax.syntaxARQ); QueryExecution queryExecution = QueryExecutionFactory.createServiceRequest( service, query ); ResultSet resultSet = queryExecution.execSelect(); - return entityCandidatesFromRS(resultSet, label); + return entityCandidatesFromRS(resultSet, queryProperties.isLabel()); } + private List entityCandidatesFromRS(ResultSet resultSet, boolean label){ List entityCandidates = new ArrayList(); QuerySolution qs; - if( label ){ - while( resultSet.hasNext() ){ - qs = resultSet.next(); - entityCandidates.add( new EntityCandidate(qs.get("o").toString(), qs.get("label").toString()) ); - } - } - else{ - while( resultSet.hasNext() ){ - qs = resultSet.next(); - entityCandidates.add( new EntityCandidate(qs.get("o").toString()) ); - } + while( resultSet.hasNext() ){ + qs = resultSet.next(); + entityCandidates.add( new EntityCandidate(qs.get("o").toString()) ); } - - - return entityCandidates; } @Override - public List getAttributes(String entity, int limit, int offset, boolean label){ + public List getAttributes(String entity, Properties queryProperties) { String queryString = queryStringTemplate; - queryString += "Select (count(?p) as ?num) ?p WHERE { ?s rdf:type/rdfs:subClassOf* <" + entity + ">." + + queryString += "Select (count(?p) as ?num) ?p FROM <" + defaultDataSetName + "> " + + " WHERE { ?s rdf:type/rdfs:subClassOf* <" + entity + ">." + " ?s ?p ?o." + - "FILTER ( regex(str(?p), 'http://dbpedia.org/property')). "; - - /*This doesn't work for some reason - * " ?p a rdf:Property. " + - */ - // Checks should the sparql query ask for a rdfs:label - // This should be used only if you are sure that there is a predicate - // rdfs:label in the data source - if( label ){ - queryString += "?p rdfs:label ?label. " + - "FILTER (lang(?label) = 'en' || lang(?label) = '') "; - } - - queryString += "}"; - /* For now I will disable order by, because it is very slow - if( limit != 0 && offset != 0 ){ - queryString += " ORDER BY ?o"; - } - */ + " ?p a rdf:Property.}"; //Add group by and order by queryString += "group by ?p order by desc(?num) "; - if( limit != 0 ){ - queryString += " LIMIT " + Integer.toString( limit ); + if( queryProperties.getLimit() != 0 ){ + queryString += " LIMIT " + Integer.toString( queryProperties.getLimit() ); } - if( offset != 0 ){ - queryString += " OFFSET " + Integer.toString( offset ); + if( queryProperties.getOffset() != 0 ){ + queryString += " OFFSET " + Integer.toString( queryProperties.getOffset() ); } System.out.println(queryString); - Query query = QueryFactory.create(queryString); + Query query = QueryFactory.create(queryString, Syntax.syntaxARQ); QueryExecution queryExecution = QueryExecutionFactory.createServiceRequest( service, query ); ResultSet resultSet = queryExecution.execSelect(); - return atributesFromRS(resultSet, label); + return atributesFromRS(resultSet, queryProperties.isLabel()); } private List atributesFromRS(ResultSet resultSet, boolean label){ List atributeCandidates = new ArrayList(); QuerySolution qs; - if( label ){ - while( resultSet.hasNext() ){ - qs = resultSet.next(); - atributeCandidates.add( new AttributeCandidate(qs.get("p").toString(), qs.get("label").toString()) ); - } - } - else{ - while( resultSet.hasNext() ){ - qs = resultSet.next(); - - atributeCandidates.add( new AttributeCandidate(qs.get("p").toString()) ); - } + while( resultSet.hasNext() ){ + qs = resultSet.next(); + + atributeCandidates.add( new AttributeCandidate(qs.get("p").toString()) ); } - - - return atributeCandidates; } @Override - public List getType(String entity, String attribute) { + public String getType(String entity, String attribute) { + String type = "string"; + String attributes[] = {attribute}; + Properties queryProperties = new Properties(); + queryProperties.setLimit(1); + + List values = getValues(entity, attributes, queryProperties, null); + ValueCandidate vCan = (ValueCandidate) values.get(0); + String toTest = vCan.getValues().get(attribute); + + try{ + Integer.parseInt(toTest); + type = "integer"; + } + catch(Exception e){ + //Do nothing + } + + try{ + Double.parseDouble(toTest); + type = "real"; + } + catch(Exception e){ + //Do nothing + } + // TODO Auto-generated method stub - return null; + return type; } @Override - public List getValues(String entity, String attributes[], int limit, int offset) { + public List getValues(String entity, String attributes[], Properties queryProperties, Expression whereExpression) { String queryString = queryStringTemplate; queryString += "Select distinct ?s " + repeateString("?o", attributes.length) + " WHERE { ?s rdf:type/rdfs:subClassOf* <" + entity + ">."; @@ -166,6 +159,37 @@ public List getValues(String entity, String attributes[], int limit, int for(int i = 0; i < attributes.length; i++){ queryString += "?s" + " <" + attributes[i] + "> " + "?o" + i + "."; } + + if(whereExpression != null){ + String operatorOuter = OperatorMapping.getOperator(whereExpression.getOperator()); + String operatorInner; + + List clauses = whereExpression.getClauses(); + + String toAppend = "FILTER( "; + for(SelectionClause one : clauses){ + if( one.isNegated() ){ + toAppend += "!"; + } + toAppend += "( "; + + if( one.getOperator() != Operator.LIKE ){ + operatorInner = OperatorMapping.getOperator(one.getOperator()); + toAppend += "xsd:double(" + variableForAttribute(attributes, one.getAttribute()) + + ")" + operatorInner + one.getValue() + ") "; + } + else{ + toAppend += "fn:matches(" + variableForAttribute(attributes, one.getAttribute()) + + "," + regexFromLike(one.getValue().toString()) + "))"; + + } + + toAppend += operatorOuter; + } + toAppend = toAppend.substring(0, toAppend.length() - operatorOuter.length()) + ")"; + System.out.println(toAppend); + queryString += toAppend; + } queryString += "}"; @@ -176,13 +200,14 @@ public List getValues(String entity, String attributes[], int limit, int */ - if( limit != 0 ){ - queryString += " LIMIT " + Integer.toString( limit ); + if( queryProperties.getLimit() != 0 ){ + queryString += " LIMIT " + Integer.toString( queryProperties.getLimit() ); } - if( offset != 0 ){ - queryString += " OFFSET " + Integer.toString( offset ); + if( queryProperties.getOffset() != 0 ){ + queryString += " OFFSET " + Integer.toString( queryProperties.getOffset() ); } - Query query = QueryFactory.create(queryString); + System.out.println(queryString); + Query query = QueryFactory.create(queryString, Syntax.syntaxARQ); QueryExecution queryExecution = QueryExecutionFactory.createServiceRequest( service, query ); ResultSet resultSet = queryExecution.execSelect(); @@ -190,6 +215,20 @@ public List getValues(String entity, String attributes[], int limit, int return valuesFromRS(resultSet, attributes); } + private String regexFromLike(String sqlString){ + String tmp = sqlString; + + tmp = tmp.replaceAll("%", ".*"); + tmp = tmp.replaceAll("_", "."); + + return "'^" + tmp + "$'"; + } + + private String variableForAttribute(String attributes[], String attribute){ + int index = java.util.Arrays.asList(attributes).indexOf(attribute); + return "?o" + index; + } + private List valuesFromRS(ResultSet resultSet, String attributes[] ){ List valueCandidates = new ArrayList(); int numOfAttributes = attributes.length; @@ -197,24 +236,15 @@ private List valuesFromRS(ResultSet resultSet, String attributes[] ){ QuerySolution qs; ValueCandidate valueCandidate; RDFNode node; - String resourceName; while( resultSet.hasNext() ){ qs = resultSet.next(); valueCandidate = new ValueCandidate(qs.get("s").toString()); for(int i = 0; i < numOfAttributes; i++){ - node = qs.get(String.format("?o%d", i)); - - if( node.isResource() ){ - resourceName = node.asResource().getURI(); - valueCandidate.addOneValue( - resourceName.substring(resourceName.lastIndexOf("/") + 1), - attributes[i]); - } - else{ - valueCandidate.addOneValue(node.toString(), attributes[i]); - } + node = qs.get(String.format("?oo%d", i)); + valueCandidate.addOneValue(node.toString(), attributes[i]); } + valueCandidates.add(valueCandidate); } @@ -226,7 +256,7 @@ private String repeateString(String s, int n){ String out = " "; for(int i = 0; i < n; i++){ - out += s + i + " "; + out += "(str(" + s + i + ") AS " + s + 'o' + i + ") "; } return out; @@ -236,44 +266,5 @@ public List getAvailableEndpoints(){ return null; } - @Override - public List getEntityCandidates(String superClass, int limit, - int offset, boolean label) { - String queryString = queryStringTemplate; - queryString += "SELECT DISTINCT (count(?o) as ?num) ?o FROM <" + defaultDataSetName + "> " + - "WHERE { ?s rdfs:subClassOf ?o. " + - "FILTER NOT EXISTS { ?o rdfs:subClassOf ?o2 }. "; - - // Checks should the sparql query ask for a rdfs:label - // This should be used only if you are sure that there is a predicate - // rdfs:label in the data source - if( label ){ - queryString += "?o rdfs:label ?label. " + - "FILTER (lang(?label) = 'en' || lang(?label) = '') "; - } - - queryString += "}"; - /* For now I will disable order by, because it is very slow - if( limit != 0 && offset != 0 ){ - queryString += " ORDER BY ?o"; - } - */ - - //Add order by and sort by - queryString += " GROUP BY ?o ORDER BY DESC(?num)"; - - if( limit != 0 ){ - queryString += " LIMIT " + Integer.toString( limit ); - } - if( offset != 0 ){ - queryString += " OFFSET " + Integer.toString( offset ); - } - System.out.println(queryString); - Query query = QueryFactory.create(queryString); - QueryExecution queryExecution = QueryExecutionFactory.createServiceRequest( - service, query ); - ResultSet resultSet = queryExecution.execSelect(); - - return entityCandidatesFromRS(resultSet, label); - } + } diff --git a/src/com/etk/data/TestRemoteSourceRDF.java b/src/com/etk/data/TestRemoteSourceRDF.java index f5d6b15..a195949 100644 --- a/src/com/etk/data/TestRemoteSourceRDF.java +++ b/src/com/etk/data/TestRemoteSourceRDF.java @@ -2,59 +2,63 @@ import java.io.UnsupportedEncodingException; import java.net.URLDecoder; +import java.util.ArrayList; import java.util.List; +import com.etk.data.query.Expression; +import com.etk.data.query.Operator; +import com.etk.data.query.Properties; +import com.etk.data.query.SelectionClause; + public class TestRemoteSourceRDF { - public static void main(String args[]){ -DataSource ds = new RemoteSourceRDF("http://dbpedia.org/sparql"); + public static void main(String args[]) { + + DataSource ds = new RemoteSourceHierarchyRDF( + "http://dbpedia.org/sparql", "http://dbpedia.org"); + Properties prop = new Properties(); - List ec = ds.getEntityCandidates(50, 0, false); + prop.setEntitySuperClass("http://schema.org/Festival"); + List ec = ds.getEntityCandidates(prop); EntityCandidate eCan; - System.out.println("*************************************Entities Test******************************************************"); - for( Object one : ec){ + for (Object one : ec) { eCan = (EntityCandidate) one; - - try { - System.out.println(URLDecoder.decode(eCan.getUri(), "utf-8") + " - " + eCan.getLabel()); - } catch (UnsupportedEncodingException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } + + System.out.println(eCan.getUri() + " - " + eCan.getLabel()); } - - System.out.println("*************************************Attributes Test******************************************************"); - List ac = ds.getAttributes("http://dbpedia.org/class/yago/SerbianRugbyUnionTeams", 50, 0, false); + + prop.setLimit(50); + List ac = ds.getAttributes("http://schema.org/Festival", prop); AttributeCandidate aCan; - for( Object one : ac){ + for (Object one : ac) { aCan = (AttributeCandidate) one; - - try { - System.out.println(URLDecoder.decode(aCan.getUri(), "utf-8") + " - " + - aCan.getLabel()); - } catch (UnsupportedEncodingException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } + + System.out.println(aCan.getUri() + " - " + aCan.getLabel()); } - - - System.out.println("*************************************Values Test******************************************************"); - String strs[] = {"http://dbpedia.org/ontology/city", "http://dbpedia.org/ontology/country", "http://dbpedia.org/ontology/sourcePlace"}; - List vc = ds.getValues("http://dbpedia.org/ontology/BodyOfWater", strs, 150, 0); + + List clauses = new ArrayList(); + clauses.add(new SelectionClause( + "http://dbpedia.org/property/yearsActive", Operator.GT, 1, + false)); + clauses.add(new SelectionClause( + "http://dbpedia.org/property/musicFestivalName", Operator.LIKE, + "%Electric%", false)); + Expression exp = new Expression(Operator.AND, clauses); + String strs[] = { "http://dbpedia.org/property/musicFestivalName", + "http://dbpedia.org/property/yearsActive" }; + List vc = ds.getValues("http://schema.org/Festival", strs, + prop, exp); ValueCandidate vCan; - - for( Object one : vc){ + for (Object one : vc) { vCan = (ValueCandidate) one; - - try { - System.out.println(URLDecoder.decode(vCan.getSubject() , "utf-8") + " - " + - URLDecoder.decode(vCan.getValues().get("http://dbpedia.org/ontology/city").split("\\^")[0], "utf-8") + " *** " + - URLDecoder.decode(vCan.getValues().get("http://dbpedia.org/ontology/country").split("\\^")[0], "utf-8") + "****" + - URLDecoder.decode(vCan.getValues().get("http://dbpedia.org/ontology/sourcePlace").split("\\^")[0], "utf-8")); - } catch (UnsupportedEncodingException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } + + System.out.println(vCan.getSubject() + + " - " + + vCan.getValues().get( + "http://dbpedia.org/property/musicFestivalName") + + " *** " + + vCan.getValues().get( + "http://dbpedia.org/property/yearsActive")); } + } } diff --git a/src/com/etk/data/query/OperatorMapping.java b/src/com/etk/data/query/OperatorMapping.java new file mode 100644 index 0000000..c81cf4f --- /dev/null +++ b/src/com/etk/data/query/OperatorMapping.java @@ -0,0 +1,25 @@ +package com.etk.data.query; + +public class OperatorMapping { + public static String getOperator( Operator o ){ + switch (o) { + case EQ: + return " = "; + case GT: + return " > "; + case LT: + return " < "; + case GE: + return " >= "; + case LE: + return " <= "; + case AND: + return " && "; + case OR: + return " || "; + + default: + return ""; + } + } +} diff --git a/src/com/etk/data/query/Properties.java b/src/com/etk/data/query/Properties.java index 327674f..44eb1a4 100644 --- a/src/com/etk/data/query/Properties.java +++ b/src/com/etk/data/query/Properties.java @@ -4,11 +4,23 @@ public class Properties { private int limit; private int offset; private boolean label; - - public Properties(int limit, int offset, boolean label) { - this.offset = offset; + private String entitySuperClass; + private int depthFrom; + private int depthTo; + + public Properties(int limit, int offset, boolean label, + String entitySuperClass, int depthFrom, int depthTo) { + super(); this.limit = limit; + this.offset = offset; this.label = label; + this.entitySuperClass = entitySuperClass; + this.depthFrom = depthFrom; + this.depthTo = depthTo; + } + + public Properties(){ + this(0, 0, false, null, 1, 1); } public int getLimit() { @@ -34,6 +46,30 @@ public boolean isLabel() { public void setLabel(boolean label) { this.label = label; } + + public String getEntitySuperClass() { + return entitySuperClass; + } + + public void setEntitySuperClass(String entitySuperClass) { + this.entitySuperClass = entitySuperClass; + } + + public int getDepthFrom() { + return depthFrom; + } + + public void setDepthFrom(int depthFrom) { + this.depthFrom = depthFrom; + } + + public int getDepthTo() { + return depthTo; + } + + public void setDepthTo(int depthTo) { + this.depthTo = depthTo; + } diff --git a/src/com/etk/data/query/SelectionClause.java b/src/com/etk/data/query/SelectionClause.java index 04ec15e..d6d9798 100644 --- a/src/com/etk/data/query/SelectionClause.java +++ b/src/com/etk/data/query/SelectionClause.java @@ -24,6 +24,14 @@ public Operator getOperator() { public Object getValue() { return value; } + + public boolean isNegated() { + return negated; + } + + public void setNegated(boolean negated) { + this.negated = negated; + } } From 5b326cdecd4eda86a92df81194c5d27a58683967 Mon Sep 17 00:00:00 2001 From: Mladen Subotic Date: Sun, 15 Dec 2013 17:33:23 +0100 Subject: [PATCH 24/37] pre merge --- src/com/etk/db/QueryExecutorImpl.java | 188 +++++++++++++++++----- src/com/etk/manager/schema/Attribute.java | 8 +- src/com/etk/manager/schema/UserTable.java | 12 +- src/tests/Test2.java | 60 +++++++ 4 files changed, 222 insertions(+), 46 deletions(-) create mode 100644 src/tests/Test2.java diff --git a/src/com/etk/db/QueryExecutorImpl.java b/src/com/etk/db/QueryExecutorImpl.java index 73f73f6..ac7f57d 100644 --- a/src/com/etk/db/QueryExecutorImpl.java +++ b/src/com/etk/db/QueryExecutorImpl.java @@ -7,6 +7,7 @@ import java.util.Map; import com.etk.data.DataSource; +import com.etk.data.RemoteSourceRDF; import com.etk.data.ValueCandidate; import com.etk.data.query.Properties; import com.etk.db.exceptions.RelsemDBException; @@ -16,6 +17,7 @@ import com.etk.manager.schema.Attribute; import com.etk.manager.schema.Schema; import com.etk.manager.schema.UserTable; +import com.etk.parser.ProjectionCell; import com.etk.parser.SelectObject; public class QueryExecutorImpl implements DBMSExecutor { @@ -24,7 +26,10 @@ public class QueryExecutorImpl implements DBMSExecutor { private DataSource dataSource; - + public QueryExecutorImpl(Schema schema) { + this.schema = schema; + this.dataSource = new RemoteSourceRDF("http://dbpedia.org/sparql"); + } @Override @@ -33,69 +38,90 @@ public List executeQuery(SelectObject sqlQuery) if(!validateQuery(sqlQuery)) { //return empty, raise exception, whatever + //check attribute ambiguity + //whether tables are prefixed + System.out.println("Query validation failed!"); return new ArrayList(); } - //create a map requested tables - List reqTables = sqlQuery.getTableNames(); - - //liste attributa za danu tablicu - Map> reqProjection = new HashMap>(); - - Map> tableSelects = new HashMap<>(); //valueCandidates for table and projection + //both from projectionCells and free attributes WITHOUT ID + Map> attributes = new HashMap>(); + Map idRequested = new HashMap(); + Map> values = new HashMap>(); - //fill reqProjection - //for each requested table, load all domain attributes and fill into reqProject - for(String rTable : reqTables) { - UserTable t = schema.getTable(rTable); - Map tAttributes = t.getAttributes(); - reqProjection.put(t.getTableName(), new ArrayList()); - for(String aName : tAttributes.keySet()) { - Attribute a = tAttributes.get(aName); - reqProjection.get(t.getTableName()).add(a); + for(String rTable : sqlQuery.getTableNames()) { + UserTable uTable = schema.getTable(rTable.toLowerCase()); + Map tAttributes = uTable.getAttributes(); + + List rAttributes = new ArrayList(); + + String tableName = uTable.getTableName(); + String tableId = uTable.getIdAttribute(); + boolean requested = false; + + + //if there exists projectionCell for given table, add it to attributes for that table + if(sqlQuery.getPrefColNames() != null) { + for(ProjectionCell pc : sqlQuery.getPrefColNames()) { + String prefix = pc.getPrefix().toLowerCase(); + if(prefix.equals(tableName)) { + if(pc.getColumnName().equalsIgnoreCase(tableId)) { // if its the table id, dont add to attributes + requested = true; + } else { + rAttributes.add(tAttributes.get(pc.getColumnName().toLowerCase())); + } + } + } } - } - - - for(String table : reqProjection.keySet()) { - List reqAttributes = reqProjection.get(table); - String[] attrUris = new String[reqAttributes.size()]; - for(int i=0;i dataCollections = new HashMap(); - for(String table : tableSelects.keySet()) { - RowCollection rc ; - - List valueCandidates = tableSelects.get(table); - for(Object vC : valueCandidates) { - ValueCandidate val = (ValueCandidate) vC; - //val is a map with attribute uris as keys - //create rows with attributes ordered as in domaintTable - - - } - } return null; } + private List getValues(List attributes, + Boolean idReq, String entityUri) { + + String[] attrUris = new String[attributes.size()]; + for(int i=0;i vcs = new ArrayList<>(); + for(Object o : this.dataSource.getValues(entityUri, attrUris, qProp)) { + vcs.add((ValueCandidate)o); + } + + return vcs; + + } + + public boolean validateQuery(SelectObject sqlQuery) { - Collection tables = schema.getTables(); List queryTables = sqlQuery.getTableNames(); for(String qTable : queryTables) { @@ -115,4 +141,80 @@ public boolean validateQuery(SelectObject sqlQuery) { return true; } + } + + +//List reqTables = sqlQuery.getTableNames(); +// +//List reqAttributes = sqlQuery.getNoPrefColNames(); +//List reqProjectionCells = sqlQuery.getPrefColNames(); +// +////liste attributa za danu tablicu +//Map> tableAttributesMap = new HashMap>(); +//Map> tableSelects = new HashMap<>(); //valueCandidates for table and projection +//Map reqId = new HashMap(); +// + +// +// +// +// +////fill reqProjection +// //for each requested table, load all domain attributes and fill into reqProject +// for(String rTable : reqTables) { +// UserTable t = schema.getTable(rTable); +// Map tAttributes = t.getAttributes(); +// tableAttributesMap.put(t.getTableName(), new ArrayList()); +// //this loop should go throguh request attributes, not table ones +// +// //for all table attributes, pass it on if it is requested by query +// for(String aName : tAttributes.keySet()) { +// Attribute a = tAttributes.get(aName); +// if(reqAttributes.contains(a.getName())) { +// tableAttributesMap.get(t.getTableName()).add(a); +// } +// //check the projection cells too +// +// } +// //pass only the table attributes requested as projectionCells +// for(ProjectionCell pc : reqProjectionCells) { +// if(pc.getPrefix().toLowerCase().equals(t.getTableName())) { +// tableAttributesMap.get(t.getTableName()).add(tAttributes.get(pc.getColumnName())); //UGH?! +// } +// } +// +// } +// +// +// +// for(String table : tableAttributesMap.keySet()) { +// List tableAttributes = tableAttributesMap.get(table); +// +// String[] attrUris = new String[tableAttributes.size()]; +// for(int i=0;i dataCollections = new HashMap(); +// +// for(String table : tableSelects.keySet()) { +// RowCollection rc ; +// +// List valueCandidates = tableSelects.get(table); +// for(Object vC : valueCandidates) { +// ValueCandidate val = (ValueCandidate) vC; +// System.out.println(val.getValues()); +// //val is a map with attribute uris as keys +// //create rows with attributes ordered as in domaintTable +// +// +// } +// } diff --git a/src/com/etk/manager/schema/Attribute.java b/src/com/etk/manager/schema/Attribute.java index 9c81bf0..7741c94 100644 --- a/src/com/etk/manager/schema/Attribute.java +++ b/src/com/etk/manager/schema/Attribute.java @@ -57,7 +57,7 @@ public void setUri(String uri) { } public void setName(String name) { - this.name = name; + this.name = name.toLowerCase(); } public void setType(Type type) { @@ -114,5 +114,11 @@ public Attribute build() { } } + + @Override + public String toString() { + return "[ attr " + name + "]"; + } + } diff --git a/src/com/etk/manager/schema/UserTable.java b/src/com/etk/manager/schema/UserTable.java index 378e401..8681f6e 100644 --- a/src/com/etk/manager/schema/UserTable.java +++ b/src/com/etk/manager/schema/UserTable.java @@ -15,9 +15,11 @@ public class UserTable { Map attributes; private String entityUri; private String entityLabel; + private String idAttribute; - public UserTable(String name, String entityUri, String entityLabel) { - this.tableName = name; + public UserTable(String name, String entityUri, String entityLabel,String idAttribute) { + this.idAttribute = idAttribute; + this.tableName = name.toLowerCase(); this.entityUri = entityUri; this.entityLabel = entityLabel; this.attributes = new HashMap(); @@ -46,4 +48,10 @@ public String getEntityUri() { public String getEntityLabel() { return entityLabel; } + + public String getIdAttribute() { + return idAttribute; + } + + } diff --git a/src/tests/Test2.java b/src/tests/Test2.java new file mode 100644 index 0000000..8a34cf7 --- /dev/null +++ b/src/tests/Test2.java @@ -0,0 +1,60 @@ +package tests; + +import com.etk.db.DBMSExecutor; +import com.etk.db.QueryExecutorImpl; +import com.etk.db.exceptions.RelsemDBException; +import com.etk.manager.User; +import com.etk.manager.schema.Attribute; +import com.etk.manager.schema.Schema; +import com.etk.manager.schema.UserTable; +import com.etk.parser.SelectObject; + +public class Test2 { + + public static void main(String[] args) { + // TODO Auto-generated method stub + SelectObject so = new SelectObject(); + + + User user = new User("marko"); + Schema schema = new Schema(user); + + +// "http://dbpedia.org/property/host" +// http://dbpedia.org/property/awards + UserTable table = new UserTable("festival", "http://schema.org/Festival", "festival", "id"); + Attribute a1 = new Attribute.Builder() + .setName("host") + .setType("string") + .setUri("http://dbpedia.org/property/host") + .setNotNull(false) + .setDefaultValue("nema") + .build(); + Attribute a2 = new Attribute.Builder() + .setName("awards") + .setType("string") + .setUri("http://dbpedia.org/property/awards") + .setNotNull(false) + .setDefaultValue("nema") + .build(); + table.addAttribute(a1); + table.addAttribute(a2); + + schema.addTable(table); + + so.addFreeColumnName("id"); + so.addFreeColumnName("host"); + so.addFreeColumnName("awards"); + so.addTableName("festival"); + + DBMSExecutor qExec = new QueryExecutorImpl(schema); + + try { + qExec.executeQuery(so); + } catch (RelsemDBException e) { + System.out.println(e.getMessage()); + } + + } + +} From 011d198a5931118a742bef933953fe9e65d0f336 Mon Sep 17 00:00:00 2001 From: w-is-h Date: Sun, 15 Dec 2013 17:51:35 +0100 Subject: [PATCH 25/37] Fix for RemoteSourceRDF, now it can be compiled --- src/com/etk/data/RemoteSourceRDF.java | 201 +++++++++++++++----------- 1 file changed, 114 insertions(+), 87 deletions(-) diff --git a/src/com/etk/data/RemoteSourceRDF.java b/src/com/etk/data/RemoteSourceRDF.java index c7fdb56..79e0905 100644 --- a/src/com/etk/data/RemoteSourceRDF.java +++ b/src/com/etk/data/RemoteSourceRDF.java @@ -3,24 +3,32 @@ import java.util.ArrayList; import java.util.List; +import com.etk.data.query.Expression; +import com.etk.data.query.Operator; +import com.etk.data.query.OperatorMapping; import com.etk.data.query.Properties; +import com.etk.data.query.SelectionClause; import com.hp.hpl.jena.query.Query; import com.hp.hpl.jena.query.QueryExecution; import com.hp.hpl.jena.query.QueryExecutionFactory; import com.hp.hpl.jena.query.QueryFactory; import com.hp.hpl.jena.query.QuerySolution; import com.hp.hpl.jena.query.ResultSet; +import com.hp.hpl.jena.query.Syntax; import com.hp.hpl.jena.rdf.model.RDFNode; public class RemoteSourceRDF implements DataSource{ String service; String queryStringTemplate; + String defaultDataSetName; - public RemoteSourceRDF( String service ){ + public RemoteSourceRDF( String service, String defaultDataSetName ){ this.service = service; - + this.defaultDataSetName = defaultDataSetName; queryStringTemplate = "PREFIX rdf: " + - "PREFIX rdfs: "; + "PREFIX rdfs: " + + "PREFIX xsd: " + + "PREFIX fn: "; } @Override @@ -87,95 +95,114 @@ private List entityCandidatesFromRS(ResultSet resultSet, boolean label){ } @Override - public List getAttributes(String entity, Properties queryProperties){ - boolean label = queryProperties.isLabel(); - int offset = queryProperties.getOffset(); - int limit = queryProperties.getLimit(); - + public List getAttributes(String entity, Properties queryProperties) { String queryString = queryStringTemplate; - queryString += "Select (count(?p) as ?num) ?p WHERE { ?s rdf:type/rdfs:subClassOf* <" + entity + ">." + + queryString += "Select (count(?p) as ?num) ?p FROM <" + defaultDataSetName + "> " + + " WHERE { ?s rdf:type/rdfs:subClassOf* <" + entity + ">." + " ?s ?p ?o." + - "FILTER ( regex(str(?p), 'http://dbpedia.org/property')). "; - - /*This doesn't work for some reason - * " ?p a rdf:Property. " + - */ - // Checks should the sparql query ask for a rdfs:label - // This should be used only if you are sure that there is a predicate - // rdfs:label in the data source - if( label ){ - queryString += "?p rdfs:label ?label. " + - "FILTER (lang(?label) = 'en' || lang(?label) = '') "; - } - - queryString += "}"; - /* For now I will disable order by, because it is very slow - if( limit != 0 && offset != 0 ){ - queryString += " ORDER BY ?o"; - } - */ + " ?p a rdf:Property.}"; //Add group by and order by queryString += "group by ?p order by desc(?num) "; - if( limit != 0 ){ - queryString += " LIMIT " + Integer.toString( limit ); + if( queryProperties.getLimit() != 0 ){ + queryString += " LIMIT " + Integer.toString( queryProperties.getLimit() ); } - if( offset != 0 ){ - queryString += " OFFSET " + Integer.toString( offset ); + if( queryProperties.getOffset() != 0 ){ + queryString += " OFFSET " + Integer.toString( queryProperties.getOffset() ); } System.out.println(queryString); - Query query = QueryFactory.create(queryString); + Query query = QueryFactory.create(queryString, Syntax.syntaxARQ); QueryExecution queryExecution = QueryExecutionFactory.createServiceRequest( service, query ); ResultSet resultSet = queryExecution.execSelect(); - return atributesFromRS(resultSet, label); + return atributesFromRS(resultSet, queryProperties.isLabel()); } private List atributesFromRS(ResultSet resultSet, boolean label){ List atributeCandidates = new ArrayList(); QuerySolution qs; - if( label ){ - while( resultSet.hasNext() ){ - qs = resultSet.next(); - atributeCandidates.add( new AttributeCandidate(qs.get("p").toString(), qs.get("label").toString()) ); - } - } - else{ - while( resultSet.hasNext() ){ - qs = resultSet.next(); - - atributeCandidates.add( new AttributeCandidate(qs.get("p").toString()) ); - } + while( resultSet.hasNext() ){ + qs = resultSet.next(); + + atributeCandidates.add( new AttributeCandidate(qs.get("p").toString()) ); } - - - return atributeCandidates; } @Override - public List getType(String entity, String attribute) { + public String getType(String entity, String attribute) { + String type = "string"; + String attributes[] = {attribute}; + Properties queryProperties = new Properties(); + queryProperties.setLimit(1); + + List values = getValues(entity, attributes, queryProperties, null); + ValueCandidate vCan = (ValueCandidate) values.get(0); + String toTest = vCan.getValues().get(attribute); + + try{ + Integer.parseInt(toTest); + type = "integer"; + } + catch(Exception e){ + //Do nothing + } + + try{ + Double.parseDouble(toTest); + type = "real"; + } + catch(Exception e){ + //Do nothing + } + // TODO Auto-generated method stub - return null; + return type; } @Override - public List getValues(String entity, String attributes[], Properties queryProperties) { + public List getValues(String entity, String attributes[], Properties queryProperties, Expression whereExpression) { String queryString = queryStringTemplate; - boolean label = queryProperties.isLabel(); - int offset = queryProperties.getOffset(); - int limit = queryProperties.getLimit(); - - queryString += "Select distinct ?s " + repeateString("?o", attributes.length) + " WHERE { ?s rdf:type/rdfs:subClassOf* <" + entity + ">."; for(int i = 0; i < attributes.length; i++){ queryString += "?s" + " <" + attributes[i] + "> " + "?o" + i + "."; } + + if(whereExpression != null){ + String operatorOuter = OperatorMapping.getOperator(whereExpression.getOperator()); + String operatorInner; + + List clauses = whereExpression.getClauses(); + + String toAppend = "FILTER( "; + for(SelectionClause one : clauses){ + if( one.isNegated() ){ + toAppend += "!"; + } + toAppend += "( "; + + if( one.getOperator() != Operator.LIKE ){ + operatorInner = OperatorMapping.getOperator(one.getOperator()); + toAppend += "xsd:double(" + variableForAttribute(attributes, one.getAttribute()) + + ")" + operatorInner + one.getValue() + ") "; + } + else{ + toAppend += "fn:matches(" + variableForAttribute(attributes, one.getAttribute()) + + "," + regexFromLike(one.getValue().toString()) + "))"; + + } + + toAppend += operatorOuter; + } + toAppend = toAppend.substring(0, toAppend.length() - operatorOuter.length()) + ")"; + System.out.println(toAppend); + queryString += toAppend; + } queryString += "}"; @@ -186,14 +213,14 @@ public List getValues(String entity, String attributes[], Properties que */ - if( limit != 0 ){ - queryString += " LIMIT " + Integer.toString( limit ); - } - if( offset != 0 ){ - queryString += " OFFSET " + Integer.toString( offset ); + if( queryProperties.getLimit() != 0 ){ + queryString += " LIMIT " + Integer.toString( queryProperties.getLimit() ); } - System.out.println(queryString); - Query query = QueryFactory.create(queryString); + if( queryProperties.getOffset() != 0 ){ + queryString += " OFFSET " + Integer.toString( queryProperties.getOffset() ); + } + System.out.println(queryString); + Query query = QueryFactory.create(queryString, Syntax.syntaxARQ); QueryExecution queryExecution = QueryExecutionFactory.createServiceRequest( service, query ); ResultSet resultSet = queryExecution.execSelect(); @@ -201,6 +228,20 @@ public List getValues(String entity, String attributes[], Properties que return valuesFromRS(resultSet, attributes); } + private String regexFromLike(String sqlString){ + String tmp = sqlString; + + tmp = tmp.replaceAll("%", ".*"); + tmp = tmp.replaceAll("_", "."); + + return "'^" + tmp + "$'"; + } + + private String variableForAttribute(String attributes[], String attribute){ + int index = java.util.Arrays.asList(attributes).indexOf(attribute); + return "?o" + index; + } + private List valuesFromRS(ResultSet resultSet, String attributes[] ){ List valueCandidates = new ArrayList(); int numOfAttributes = attributes.length; @@ -208,24 +249,15 @@ private List valuesFromRS(ResultSet resultSet, String attributes[] ){ QuerySolution qs; ValueCandidate valueCandidate; RDFNode node; - String resourceName; while( resultSet.hasNext() ){ qs = resultSet.next(); valueCandidate = new ValueCandidate(qs.get("s").toString()); for(int i = 0; i < numOfAttributes; i++){ - node = qs.get(String.format("?o%d", i)); - - if( node.isResource() ){ - resourceName = node.asResource().getURI(); - valueCandidate.addOneValue( - resourceName.substring(resourceName.lastIndexOf("/") + 1), - attributes[i]); - } - else{ - valueCandidate.addOneValue(node.toString(), attributes[i]); - } + node = qs.get(String.format("?oo%d", i)); + valueCandidate.addOneValue(node.toString(), attributes[i]); } + valueCandidates.add(valueCandidate); } @@ -235,10 +267,10 @@ private List valuesFromRS(ResultSet resultSet, String attributes[] ){ private String repeateString(String s, int n){ String out = " "; - - for(int i = 0; i < n; i++){ - out += s + i + " "; - } + + for(int i = 0; i < n; i++){ + out += "(str(" + s + i + ") AS " + s + 'o' + i + ") "; + } return out; } @@ -247,10 +279,5 @@ public List getAvailableEndpoints(){ return null; } - @Override - public List getEntityCandidates(String superClass, int limit, - int offset, boolean label) { - // TODO Auto-generated method stub - return null; - } -} + +} \ No newline at end of file From 4adbde643e7dee3657f7421cf50bc3fab751b334 Mon Sep 17 00:00:00 2001 From: Mladen Subotic Date: Sun, 15 Dec 2013 17:53:20 +0100 Subject: [PATCH 26/37] disi --- src/com/etk/db/QueryExecutorImpl.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/com/etk/db/QueryExecutorImpl.java b/src/com/etk/db/QueryExecutorImpl.java index ac7f57d..17d214f 100644 --- a/src/com/etk/db/QueryExecutorImpl.java +++ b/src/com/etk/db/QueryExecutorImpl.java @@ -110,9 +110,9 @@ private List getValues(List attributes, for(int i=0;i vcs = new ArrayList<>(); - for(Object o : this.dataSource.getValues(entityUri, attrUris, qProp)) { + for(Object o : this.dataSource.getValues(entityUri, attrUris, qProp,null)) { vcs.add((ValueCandidate)o); } From 144506ff5cc64da212f3d292ecba53674e84364a Mon Sep 17 00:00:00 2001 From: Mladen Subotic Date: Mon, 16 Dec 2013 00:17:53 +0100 Subject: [PATCH 27/37] demoable query executor --- src/com/etk/db/QueryExecutorImpl.java | 92 ++++++++++++++++++++++++++- src/com/etk/db/model/RowImple.java | 2 +- src/tests/Test2.java | 39 +++++++++++- 3 files changed, 128 insertions(+), 5 deletions(-) diff --git a/src/com/etk/db/QueryExecutorImpl.java b/src/com/etk/db/QueryExecutorImpl.java index 17d214f..81408ea 100644 --- a/src/com/etk/db/QueryExecutorImpl.java +++ b/src/com/etk/db/QueryExecutorImpl.java @@ -7,15 +7,19 @@ import java.util.Map; import com.etk.data.DataSource; +import com.etk.data.RemoteSourceHierarchyRDF; import com.etk.data.RemoteSourceRDF; import com.etk.data.ValueCandidate; import com.etk.data.query.Properties; import com.etk.db.exceptions.RelsemDBException; +import com.etk.db.model.Row; import com.etk.db.model.RowCollection; +import com.etk.db.model.RowImple; import com.etk.db.model.Table; import com.etk.db.query.QueryResult; import com.etk.manager.schema.Attribute; import com.etk.manager.schema.Schema; +import com.etk.manager.schema.Type; import com.etk.manager.schema.UserTable; import com.etk.parser.ProjectionCell; import com.etk.parser.SelectObject; @@ -28,7 +32,8 @@ public class QueryExecutorImpl implements DBMSExecutor { public QueryExecutorImpl(Schema schema) { this.schema = schema; - this.dataSource = new RemoteSourceRDF("http://dbpedia.org/sparql"); + this.dataSource = new RemoteSourceHierarchyRDF( + "http://dbpedia.org/sparql", "http://dbpedia.org"); } @@ -49,6 +54,7 @@ public List executeQuery(SelectObject sqlQuery) Map> attributes = new HashMap>(); Map idRequested = new HashMap(); Map> values = new HashMap>(); + Map> rows = new HashMap>(); for(String rTable : sqlQuery.getTableNames()) { @@ -87,15 +93,79 @@ public List executeQuery(SelectObject sqlQuery) } } + //add attributes from join conditions + idRequested.put(tableName, requested); attributes.put(tableName, rAttributes); values.put(tableName, getValues(attributes.get(tableName),idRequested.get(tableName),uTable.getEntityUri())); + rows.put(tableName, getRowCollection(values.get(tableName), attributes.get(tableName), true)); + + } + for(String tbl : rows.keySet()) { + final int rowCount = rows.get(tbl).size(); + boolean id = idRequested.get(tbl); + int attrCount = attributes.get(tbl).size(); + List tableAttributes = attributes.get(tbl); + + int totalCount = id ? attrCount + 1 : attrCount ; + final String[] attrs = new String[totalCount]; + final Type[] types = new Type[totalCount]; + + if(id) { ///ugh :// + attrs[0] = schema.getTable(tbl).getIdAttribute(); + types[0] = Type.STRING; + } + + for(int i = (id ? 1 : 0); i < totalCount ; i++) { + attrs[i] = tableAttributes.get(i - (id?1 : 0)).getName(); + types[i] = Type.STRING; + } + + final List rws = new ArrayList(); + for(Row r : rows.get(tbl)) { + String[] data = new String[totalCount]; + for(int i = 0; i < totalCount ; i++) { + data[i] = r.getValue(i).toString(); + } + rws.add(data); + } + + + QueryResult qr = new QueryResult() { + + @Override + public int getSize() { + return rowCount; + } + + @Override + public List getData() { + return rws; + } + + @Override + public String[] getAttributes() { + return attrs; + } + + @Override + public Type[] getAttributeTypes() { + return types; + } + }; + + List qrs = new ArrayList(); + qrs.add(qr); + return qrs; + + + } @@ -103,6 +173,26 @@ public List executeQuery(SelectObject sqlQuery) return null; } + private List getRowCollection(List values, List attributes, boolean id) { + List rows = new ArrayList(); + Map valueMap = null; + + for(ValueCandidate vc : values) { + valueMap = vc.getValues(); + Object[] rowValues = new Object[id ? valueMap.size()+1 : valueMap.size()]; + if(id) { + rowValues[0] = vc.getSubject(); + } + for(int i = ( id ? 1 : 0 ) ; i < rowValues.length ; i++) { + rowValues[i] = valueMap.get(attributes.get(i - (id?1 : 0)).getUri()); + } + rows.add(new RowImple(rowValues)); + } + + //create table out of it + return rows; + } + private List getValues(List attributes, Boolean idReq, String entityUri) { diff --git a/src/com/etk/db/model/RowImple.java b/src/com/etk/db/model/RowImple.java index 714389b..caef0b0 100644 --- a/src/com/etk/db/model/RowImple.java +++ b/src/com/etk/db/model/RowImple.java @@ -32,7 +32,7 @@ public int getLength() { public String toString() { StringBuilder sb = new StringBuilder(); for(int i = 0; i Date: Mon, 16 Dec 2013 19:57:04 +0100 Subject: [PATCH 28/37] mock schema object --- src/com/etk/manager/SchemaManager.java | 6 ++- src/mock/MockedSchema.java | 55 ++++++++++++++++++++++++++ 2 files changed, 60 insertions(+), 1 deletion(-) create mode 100644 src/mock/MockedSchema.java diff --git a/src/com/etk/manager/SchemaManager.java b/src/com/etk/manager/SchemaManager.java index c1772dd..3fcdcb3 100644 --- a/src/com/etk/manager/SchemaManager.java +++ b/src/com/etk/manager/SchemaManager.java @@ -7,6 +7,8 @@ import java.util.List; import java.util.Map; +import mock.MockedSchema; + /** * Created by mladen on 11/9/13. */ @@ -20,7 +22,9 @@ public boolean validateQuery(String queryDescription, Schema schema) { //someint } public void createSchema(User user) { - schemas.put(user,new Schema(user)); + Schema newSchema = new MockedSchema(user); + schemas.put(user,newSchema); + } public Schema getSchema(User user) { diff --git a/src/mock/MockedSchema.java b/src/mock/MockedSchema.java new file mode 100644 index 0000000..78c2bd7 --- /dev/null +++ b/src/mock/MockedSchema.java @@ -0,0 +1,55 @@ +package mock; + +import com.etk.manager.User; +import com.etk.manager.schema.Attribute; +import com.etk.manager.schema.Schema; +import com.etk.manager.schema.UserTable; + +public class MockedSchema extends Schema { + public MockedSchema(User user) { + super(user); + + UserTable table = new UserTable("festival", "http://schema.org/Festival", "festival", "id"); + Attribute a1 = new Attribute.Builder() + .setName("host") + .setType("string") + .setUri("http://dbpedia.org/property/host") + .setNotNull(false) + .setDefaultValue("nema") + .build(); + Attribute a2 = new Attribute.Builder() + .setName("awards") + .setType("string") + .setUri("http://dbpedia.org/property/awards") + .setNotNull(false) + .setDefaultValue("nema") + .build(); + table.addAttribute(a1); + table.addAttribute(a2); + + this.addTable(table); + + + UserTable table2 = new UserTable("award", "http://dbpedia.org/ontology/Award", "award", "id"); + Attribute b1 = new Attribute.Builder() + .setName("name") + .setType("string") + .setUri("http://dbpedia.org/property/name") + .setNotNull(false) + .setDefaultValue("nema") + .build(); + Attribute b2 = new Attribute.Builder() + .setName("year") + .setType("string") + .setUri("http://dbpedia.org/property/year") + .setNotNull(false) + .setDefaultValue("nema") + .build(); + + table2.addAttribute(b1); + table2.addAttribute(b2); + this.addTable(table2); + + } + +} From cbce4f3990f8de2b490f4755d970cba541534584 Mon Sep 17 00:00:00 2001 From: Mladen Subotic Date: Mon, 16 Dec 2013 22:21:41 +0100 Subject: [PATCH 29/37] random comment --- src/com/etk/db/QueryExecutorImpl.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/com/etk/db/QueryExecutorImpl.java b/src/com/etk/db/QueryExecutorImpl.java index 81408ea..5470ccf 100644 --- a/src/com/etk/db/QueryExecutorImpl.java +++ b/src/com/etk/db/QueryExecutorImpl.java @@ -231,7 +231,7 @@ public boolean validateQuery(SelectObject sqlQuery) { return true; } - + //random comment } From cbcd2892036d8feae7e5633df5dcbf8ea45059d4 Mon Sep 17 00:00:00 2001 From: Mladen Subotic Date: Mon, 16 Dec 2013 22:56:42 +0100 Subject: [PATCH 30/37] merging hell --- src/com/etk/manager/schema/UserTable.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/com/etk/manager/schema/UserTable.java b/src/com/etk/manager/schema/UserTable.java index 8681f6e..63ff057 100644 --- a/src/com/etk/manager/schema/UserTable.java +++ b/src/com/etk/manager/schema/UserTable.java @@ -10,7 +10,7 @@ * Created by mladen on 11/9/13. */ public class UserTable { - +//randcomment private String tableName; //mapping how? Map attributes; private String entityUri; From 212d8b74dbe17418b6d8154abf78ffa4247f0534 Mon Sep 17 00:00:00 2001 From: w-is-h Date: Tue, 17 Dec 2013 22:03:54 +0100 Subject: [PATCH 31/37] Update of HierarchyRDF --- .../etk/data/RemoteSourceHierarchyRDF.java | 34 ++++++++++++------- 1 file changed, 22 insertions(+), 12 deletions(-) diff --git a/src/com/etk/data/RemoteSourceHierarchyRDF.java b/src/com/etk/data/RemoteSourceHierarchyRDF.java index 0465b0b..f6e1f3d 100644 --- a/src/com/etk/data/RemoteSourceHierarchyRDF.java +++ b/src/com/etk/data/RemoteSourceHierarchyRDF.java @@ -25,21 +25,28 @@ public class RemoteSourceHierarchyRDF implements DataSource{ String queryStringTemplate; String defaultDataSetName; - public RemoteSourceHierarchyRDF( String service, String defaultDataSetName ){ + public RemoteSourceHierarchyRDF( String service ){ this.service = service; - this.defaultDataSetName = defaultDataSetName; + this.defaultDataSetName = null; queryStringTemplate = "PREFIX rdf: " + "PREFIX rdfs: " + - "PREFIX xsd: " + - "PREFIX fn: "; + "PREFIX xsd: "; + } + + public RemoteSourceHierarchyRDF( String service, String defaultDataSetName ){ + this(service); + this.defaultDataSetName = defaultDataSetName; } @Override public List getEntityCandidates(Properties queryProperties) { String queryString = queryStringTemplate; - queryString += "SELECT DISTINCT (count(?o) as ?num) ?o FROM <" + defaultDataSetName + "> " + - "WHERE { "; + queryString += "SELECT DISTINCT (count(?o) as ?num) ?o "; + if(defaultDataSetName != null){ + queryString += "FROM <" + defaultDataSetName + "> "; + } + queryString += "WHERE { "; if( queryProperties.getEntitySuperClass() != null ){ queryString += "?o rdfs:subClassOf{" + queryProperties.getDepthFrom() + "," + @@ -60,7 +67,7 @@ public List getEntityCandidates(Properties queryProperties) { if( queryProperties.getOffset() != 0 ){ queryString += " OFFSET " + Integer.toString( queryProperties.getOffset() ); } - + System.out.println(queryString); Query query = QueryFactory.create(queryString, Syntax.syntaxARQ); QueryExecution queryExecution = QueryExecutionFactory.createServiceRequest( service, query ); @@ -84,10 +91,13 @@ private List entityCandidatesFromRS(ResultSet resultSet, boolean label){ @Override public List getAttributes(String entity, Properties queryProperties) { String queryString = queryStringTemplate; - queryString += "Select (count(?p) as ?num) ?p FROM <" + defaultDataSetName + "> " + - " WHERE { ?s rdf:type/rdfs:subClassOf* <" + entity + ">." + - " ?s ?p ?o." + - " ?p a rdf:Property.}"; + queryString += "Select (count(?p) as ?num) ?p "; + if(defaultDataSetName != null){ + queryString += "FROM <" + defaultDataSetName + "> "; + } + queryString += " WHERE { ?s rdf:type/rdfs:subClassOf* <" + entity + ">." + + " ?s ?p ?o." + + " ?p a rdf:Property.}"; //Add group by and order by queryString += "group by ?p order by desc(?num) "; @@ -179,7 +189,7 @@ public List getValues(String entity, String attributes[], Properties que ")" + operatorInner + one.getValue() + ") "; } else{ - toAppend += "fn:matches(" + variableForAttribute(attributes, one.getAttribute()) + + toAppend += "regex(" + variableForAttribute(attributes, one.getAttribute()) + "," + regexFromLike(one.getValue().toString()) + "))"; } From df31abfe4391526c36513c9eabdd951a58395f79 Mon Sep 17 00:00:00 2001 From: Mladen Subotic Date: Tue, 17 Dec 2013 22:04:21 +0100 Subject: [PATCH 32/37] dasdasd --- src/com/etk/db/QueryExecutorImpl.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/com/etk/db/QueryExecutorImpl.java b/src/com/etk/db/QueryExecutorImpl.java index 5470ccf..ccfbf35 100644 --- a/src/com/etk/db/QueryExecutorImpl.java +++ b/src/com/etk/db/QueryExecutorImpl.java @@ -201,7 +201,7 @@ private List getValues(List attributes, attrUris[i] = attributes.get(i).getUri(); } Properties qProp = new Properties(20, 0, false,"",0,0); - List vcs = new ArrayList<>(); + List vcs = new ArrayList(); for(Object o : this.dataSource.getValues(entityUri, attrUris, qProp,null)) { vcs.add((ValueCandidate)o); } @@ -231,7 +231,7 @@ public boolean validateQuery(SelectObject sqlQuery) { return true; } - //random comment + } From e2f66f817c724f5f67eecaba2149215f5c3f61b3 Mon Sep 17 00:00:00 2001 From: Mladen Subotic Date: Tue, 17 Dec 2013 22:11:44 +0100 Subject: [PATCH 33/37] gitignore --- .gitignore | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.gitignore b/.gitignore index 3396968..ac4abb3 100644 --- a/.gitignore +++ b/.gitignore @@ -13,6 +13,9 @@ tmp/**/* out/* bin/** +src/META-INF +src/META-INF/* + .idea/* .project .metadata From 56db387b364590cc72f3a18b774f0651313b2677 Mon Sep 17 00:00:00 2001 From: Mladen Subotic Date: Tue, 17 Dec 2013 23:11:26 +0100 Subject: [PATCH 34/37] added mocked SelectObject for driver testing --- src/mock/MockSelectObject.java | 38 ++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) create mode 100644 src/mock/MockSelectObject.java diff --git a/src/mock/MockSelectObject.java b/src/mock/MockSelectObject.java new file mode 100644 index 0000000..62e155c --- /dev/null +++ b/src/mock/MockSelectObject.java @@ -0,0 +1,38 @@ +package mock; + +import java.util.ArrayList; + +import com.etk.parser.ProjectionCell; +import com.etk.parser.SelectObject; + +public class MockSelectObject extends SelectObject { + + public MockSelectObject() { + super(); + } + + @Override + public ArrayList getNoPrefColNames() { + ArrayList ret = new ArrayList(); + ret.add("host"); + ret.add("awards"); + return ret; + + } + + @Override + public ArrayList getPrefColNames() { + ArrayList ret = new ArrayList(); + return ret; + } + + @Override + public ArrayList getTableNames() { + ArrayList ret = new ArrayList(); + ret.add("festival"); + return ret; + + } + +} + \ No newline at end of file From cd0954fe1d12f165f5a5b47f12eb676c006a14cc Mon Sep 17 00:00:00 2001 From: Mladen Subotic Date: Wed, 18 Dec 2013 00:40:43 +0100 Subject: [PATCH 35/37] added sort flag to properties --- src/com/etk/data/query/Properties.java | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/com/etk/data/query/Properties.java b/src/com/etk/data/query/Properties.java index 44eb1a4..da29467 100644 --- a/src/com/etk/data/query/Properties.java +++ b/src/com/etk/data/query/Properties.java @@ -7,6 +7,7 @@ public class Properties { private String entitySuperClass; private int depthFrom; private int depthTo; + private boolean sort; public Properties(int limit, int offset, boolean label, String entitySuperClass, int depthFrom, int depthTo) { @@ -70,6 +71,14 @@ public int getDepthTo() { public void setDepthTo(int depthTo) { this.depthTo = depthTo; } + + public boolean isSort() { + return sort; + } + + public void setSort(boolean sort) { + this.sort = sort; + } From b53309a957779a291946b96e5b0a74f8c4b3fb05 Mon Sep 17 00:00:00 2001 From: Mladen Subotic Date: Wed, 18 Dec 2013 23:48:51 +0100 Subject: [PATCH 36/37] dsa --- src/com/etk/data/RemoteSourceHierarchyRDF.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/com/etk/data/RemoteSourceHierarchyRDF.java b/src/com/etk/data/RemoteSourceHierarchyRDF.java index f6e1f3d..a829563 100644 --- a/src/com/etk/data/RemoteSourceHierarchyRDF.java +++ b/src/com/etk/data/RemoteSourceHierarchyRDF.java @@ -3,7 +3,7 @@ import java.util.ArrayList; import java.util.List; -import sun.misc.Regexp; + import com.etk.data.query.Expression; import com.etk.data.query.Operator; From 0439796f467df2f4722d97fa732e6892bef67dd6 Mon Sep 17 00:00:00 2001 From: Mladen Subotic Date: Thu, 19 Dec 2013 00:11:44 +0100 Subject: [PATCH 37/37] physically merged for beta --- src/com/etk/network/client/Client.java | 24 +- src/com/etk/network/server/ByteTokenizer.java | 201 +++++++ .../etk/network/server/ConnectionHandler.java | 67 +++ src/com/etk/network/server/JDBCServer.java | 56 +- src/com/etk/network/server/MsgParser.java | 38 ++ src/com/etk/network/server/Receiver.java | 183 ++++++ src/com/etk/network/server/Sender.java | 214 ++++++- .../etk/network/server/SessionHandler.java | 546 +++++------------- src/com/etk/parser/SELECTBaseListener.java | 4 - src/com/etk/parser/SELECTListener.java | 2 - src/com/etk/parser/SELECTMain.java | 44 ++ src/com/etk/parser/SELECTParser.java | 2 - 12 files changed, 896 insertions(+), 485 deletions(-) create mode 100644 src/com/etk/network/server/ByteTokenizer.java create mode 100644 src/com/etk/network/server/ConnectionHandler.java create mode 100644 src/com/etk/network/server/MsgParser.java create mode 100644 src/com/etk/network/server/Receiver.java create mode 100644 src/com/etk/parser/SELECTMain.java diff --git a/src/com/etk/network/client/Client.java b/src/com/etk/network/client/Client.java index 3d6bd56..77ef862 100644 --- a/src/com/etk/network/client/Client.java +++ b/src/com/etk/network/client/Client.java @@ -37,7 +37,7 @@ public Client() { try { option = Integer.parseInt(br_.readLine()); - } catch (IOException e1) { + } catch (NumberFormatException | IOException e1) { } switch (option) { @@ -79,12 +79,18 @@ private void query(Connection conn, ArrayList list, String query) { try { Statement st = conn.createStatement(); // the syntax for FROM is schema.table - ResultSet rs = st.executeQuery("SELECT a.d, a.c, b.d FROM a, b"); + ResultSet rs = st.executeQuery(query); + + // getColumnNames from parser + + String[] columns = { "host", "award" }; + + + int i=0; while (rs.next()) { - String name = rs.getString("name"); - System.out.println(name); - String surname = rs.getString("surname"); - System.out.println(surname); + String value = rs.getString(columns[i]); + System.out.println(value); + i++; // Date date = rs.getDate("date"); // System.out.println(date.toString()); @@ -92,9 +98,11 @@ private void query(Connection conn, ArrayList list, String query) { rs.close(); st.close(); } catch (SQLException se) { - System.err.println("Threw a SQLException."); + // System.err.println("Threw a SQLException."); + // System.err.println(se.getErrorCode()); + System.err.println("An error occurred:"); System.err.println(se.getMessage()); - se.printStackTrace(); + //se.printStackTrace(); } } diff --git a/src/com/etk/network/server/ByteTokenizer.java b/src/com/etk/network/server/ByteTokenizer.java new file mode 100644 index 0000000..c4e3314 --- /dev/null +++ b/src/com/etk/network/server/ByteTokenizer.java @@ -0,0 +1,201 @@ +package com.etk.network.server; + +import java.util.Enumeration; +import java.util.NoSuchElementException; + +public class ByteTokenizer implements Enumeration { + + private int currentPosition; + private int newPosition; + private int maxPosition; + + private byte[] bytes; + private byte[] delimiters; + + /** + * Constructs a bytes array tokenizer for the specified bytes. The bytes in + * the delimiters argument are the delimiters for separating + * tokens. Delimiter bytes themselves will not be treated as tokens. + *

+ * Note that if delimiters is null, this constructor does + * not throw an exception. However, trying to invoke other methods on the + * resulting ByteTokenizer may result in a + * NullPointerException. + * + * @param bytes + * a bytes array to be parsed + * @param delimiters + * a bytes array delimiters + * @exception NullPointerException + * if bytes is null + */ + public ByteTokenizer(byte[] bytes, byte[] delimiters) { + this.bytes = bytes; + this.delimiters = delimiters; + currentPosition = 0; + newPosition = -1; + maxPosition = bytes.length; + } + + /** + * Constructs a bytes array tokenizer for the specified bytes. The byte + * delimiter argument is the delimiter for separating tokens. + * Delimiter byte itself will not be treated as tokens. + *

+ * Note that if delimiter is null, this constructor does + * not throw an exception. However, trying to invoke other methods on the + * resulting ByteTokenizer may result in a + * NullPointerException. + * + * @param bytes + * a bytes array to be parsed + * @param delimiter + * a byte delimiter + * @exception NullPointerException + * if bytes is null + */ + public ByteTokenizer(byte[] bytes, byte delimiter) { + this(bytes, new byte[] { delimiter }); + } + + /** + * Tests if there are more tokens available from this tokenizer's bytes + * array. If this method returns true, then a subsequent call to + * nextToken with no argument will successfully return a token. + * + * @return true if there are more tokens; false + * otherwise. + */ + public boolean hasMoreTokens() { + newPosition = skipDelimiters(currentPosition); + return (newPosition < maxPosition); + } + + /** + * Returns the same value as the hasMoreTokens method. It + * exists so that this class can implement the Enumeration + * interface. + * + * @return true if there are more tokens; false + * otherwise. + * @see java.util.Enumeration + */ + public boolean hasMoreElements() { + return hasMoreTokens(); + } + + /** + * Returns the next token from this bytes array tokenizer. + * + * @return the next token from this bytes array tokenizer. + * @exception NoSuchElementException + * if there are no more tokens in this tokenizer's bytes + * array. + */ + public byte[] nexToken() { + currentPosition = (newPosition >= 0) ? newPosition + : skipDelimiters(currentPosition); + + // Reset + newPosition = -1; + + if (currentPosition >= maxPosition) { + throw new NoSuchElementException( + "current token position is out of bound."); + } + final int startPosition = currentPosition; + currentPosition = scanToken(currentPosition); + final int length = currentPosition - startPosition; + final byte[] token = new byte[length]; + System.arraycopy(bytes, startPosition, token, 0, length); + return token; + } + + /** + * Returns the same value as the nextToken method, except that + * its declared return value is Object rather than + * String. It exists so that this class can implement the + * Enumeration interface. + * + * @return the next token in the bytes array. + * @exception NoSuchElementException + * if there are no more tokens in this tokenizer's bytes + * array. + * @see java.util.Enumeration + */ + public byte[] nextElement() { + return nexToken(); + } + + /** + * Calculates the number of times that this tokenizer's + * nextToken method can be called before it generates an + * exception. The current position is not advanced. + * + * @return the number of tokens remaining in the bytes array using the + * current delimiter set. + */ + public int countTokens() { + int tokenNums = 0; + int position = currentPosition; + while (position < maxPosition) { + position = skipDelimiters(position); + if (position >= maxPosition) { + break; + } + position = scanToken(position); + tokenNums++; + } + return tokenNums; + } + + /** + * Skips delimiters starting from the specified position. Returns the index + * of the first non-delimiter byte at or after startPosition. + */ + private int skipDelimiters(final int startPosition) { + if (delimiters == null) { + throw new NullPointerException("delimiters"); + } + int position = startPosition; + while (position < maxPosition) { + if (isDelimiter(position)) { + position += delimiters.length; + } else + break; + } + return position; + } + + /** + * Skips ahead from startPosition and returns the index of the next + * delimiter byte encountered, or maxPosition if no such delimiter is found. + */ + private int scanToken(final int startPosition) { + int position = startPosition; + while (position < maxPosition) { + if (isDelimiter(position)) { + break; + } + position++; + } + return position; + } + + private boolean isDelimiter(final int startPosition) { + int position = startPosition; + boolean isDelimiter = true; + while ((position < maxPosition) && isDelimiter) { + int nDelimiter = 0; + while (nDelimiter < delimiters.length) { + if (bytes[startPosition + nDelimiter] != delimiters[nDelimiter]) { + isDelimiter = false; + break; + } + nDelimiter++; + } + position++; + } + return isDelimiter; + } +} diff --git a/src/com/etk/network/server/ConnectionHandler.java b/src/com/etk/network/server/ConnectionHandler.java new file mode 100644 index 0000000..c957587 --- /dev/null +++ b/src/com/etk/network/server/ConnectionHandler.java @@ -0,0 +1,67 @@ +package com.etk.network.server; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; +import java.net.Socket; + +public class ConnectionHandler implements Runnable { + + private Socket server_; + private Sender sender_; + private Receiver receiver_; + private final String pass_ = "postgres"; + + public ConnectionHandler(Socket server) { + this.server_ = server; + try { + this.sender_ = new Sender(new DataOutputStream( + server_.getOutputStream())); + this.receiver_ = new Receiver(new DataInputStream( + server_.getInputStream())); + } catch (IOException e) { + e.printStackTrace(); + } + } + + @Override + public void run() { + if(!this.receiver_.receiveAuthMessage()){ + this.sender_.sendWeDontManageSSL(); + this.sender_.flush(); + this.receiver_.receiveAuthMessage(); + } + + // ask for the password + this.sender_ + .sendAuthenticationOkMessage(Sender.AuthEnum.ClearTextPasswordRequired); + this.sender_.flush(); + + String password = this.receiver_.getPassword(); + System.out.println("Password: " + password); + + if (!password.equals(this.pass_)) { + this.sender_.sendErrorResponse("Wrong Password!"); + return; + } + + this.sender_.sendAuthenticationOkMessage(Sender.AuthEnum.AuthOK); + this.sender_.sendServerVersionMessage(); + this.sender_.sendReadyForQueryMessage(); + this.sender_.flush(); + + // Socket server = socket_.accept(); + // while(true){ + // DataInputStream dataInputStreamSession = new DataInputStream( + // server_.getInputStream()); + // SessionHandler sessionHandler = new SessionHandler(server_, + // dataInputStreamSession); + // Thread session = new Thread(sessionHandler); + // session.start(); + // } + + SessionHandler sessionHandler = new SessionHandler(server_); + Thread session = new Thread(sessionHandler); + session.start(); + } +} diff --git a/src/com/etk/network/server/JDBCServer.java b/src/com/etk/network/server/JDBCServer.java index 6f4de5a..1e62bb8 100644 --- a/src/com/etk/network/server/JDBCServer.java +++ b/src/com/etk/network/server/JDBCServer.java @@ -6,27 +6,39 @@ public class JDBCServer { - private static int port=5000; - //TODO implement max number of connections? - - // Listen for incoming connections and handle them - public static void main(String[] args) { - try{ - ServerSocket listener = new ServerSocket(port); - Socket server; - System.out.println("server started!"); - while(true){ - server = listener.accept(); - System.out.println("connection accepted"); - SessionHandler conn_c= new SessionHandler(server); - Thread t = new Thread(conn_c); - t.start(); - } - - } catch (IOException ioe) { - System.out.println("IOException on socket listen: " + ioe); - ioe.printStackTrace(); - } - } + // TODO implement max number of connections? + private static int port = 5000; + + /** + * Listen for incoming connections and handle them + * + * @param args + */ + public static void main(String[] args) { + + boolean connected_ = false; + + try { + ServerSocket socket = new ServerSocket(port); + System.out.println("server started!"); + while (true) { + Socket server = socket.accept(); + System.out.println("connection accepted"); + ConnectionHandler connectionHandler = new ConnectionHandler( + server); + Thread connection = new Thread(connectionHandler); + connection.start(); + + // Til here is ok, but suddenly boum + // SessionHandler sessionHandler = new SessionHandler(server); + // Thread session = new Thread(sessionHandler); + // session.start(); + } + + } catch (IOException ioe) { + System.out.println("IOException on socket listen: " + ioe); + ioe.printStackTrace(); + } + } } diff --git a/src/com/etk/network/server/MsgParser.java b/src/com/etk/network/server/MsgParser.java new file mode 100644 index 0000000..229f397 --- /dev/null +++ b/src/com/etk/network/server/MsgParser.java @@ -0,0 +1,38 @@ +package com.etk.network.server; + +import java.io.UnsupportedEncodingException; +import java.nio.ByteBuffer; + +public class MsgParser { + + public MsgParser() { + } + + public short parseShort(byte[] bytes) throws IllegalArgumentException { + if (bytes.length < 2) + throw new IllegalArgumentException( + "The array of bytes which represent the short int has less than 2 bytes"); + if (bytes.length > 2) + throw new IllegalArgumentException( + "The array of bytes which represent the short int has more than 2 bytes"); + return ByteBuffer.wrap(bytes).getShort(); + + } + + public int parseInt(byte[] bytes) throws IllegalArgumentException { + if (bytes.length < 4) + throw new IllegalArgumentException( + "The array of bytes which represent the integer has less than 4 bytes"); + if (bytes.length > 4) + throw new IllegalArgumentException( + "The array of bytes which represent the integer has more than 4 bytes"); + int len = ByteBuffer.wrap(bytes).getInt(); + return len; + } + + public String parseMsg(byte[] bytes) throws UnsupportedEncodingException { + String msgString = new String(bytes, "UTF-8"); + return msgString; + } + +} diff --git a/src/com/etk/network/server/Receiver.java b/src/com/etk/network/server/Receiver.java new file mode 100644 index 0000000..c72cb8b --- /dev/null +++ b/src/com/etk/network/server/Receiver.java @@ -0,0 +1,183 @@ +package com.etk.network.server; + +import java.io.DataInputStream; +import java.io.IOException; +import java.io.UnsupportedEncodingException; +import java.nio.ByteBuffer; +import java.util.Arrays; + +public class Receiver { + + private DataInputStream dataInputStream_; + private MsgParser parser_; + private short protocolMinorVersion_; + private short protocolMajorVersion_; + private String username_; + private String dbName_; + + public Receiver(DataInputStream input) { + this.dataInputStream_ = input; + this.parser_ = new MsgParser(); + this.protocolMajorVersion_ = 0; + this.protocolMinorVersion_ = 0; + this.username_ = null; + this.dbName_ = null; + } + + /** + * + * @return + */ + public String getUsername() { + return this.username_; + } + + /** + * + * @return + */ + public String getDBName() { + return this.dbName_; + } + + /** + * + * @return + */ + public String getPassword() { + try { + this.dataInputStream_.readByte(); + int msgLength = dataInputStream_.readInt(); + // - 4 for message lenght + byte[] buf = new byte[msgLength - 4]; + this.dataInputStream_.read(buf); + byte delim = 0; + ByteTokenizer bt = new ByteTokenizer(buf, delim); + return this.parser_.parseMsg(bt.nexToken()); + } catch (IOException e) { + System.out.println("Error in getPassword: "); + e.printStackTrace(); + } + return null; + } + + /** + * + * @return + * @throws IOException + */ + public int available() throws IOException { + return this.dataInputStream_.available(); + } + + /** + * + * @return + */ + public boolean receiveAuthMessage() { + try { + int msgLen = dataInputStream_.readInt(); + if (msgLen == 8) { + // THIS MEANS IT IS AN SSL REQUEST + // the following line is only to empty the inputStream + dataInputStream_.readInt(); + return false; + } else { + this.protocolMajorVersion_ = dataInputStream_.readShort(); + this.protocolMinorVersion_ = dataInputStream_.readShort(); + // System.out.println('v' + protocolMajorVersion_ + '.' + + // protocolMinorVersion_); + + // -4 for message lenght, -2 for the protocolMajorVersion_, -2 + // for the protocolMinorVersion_ + byte[] buf = new byte[msgLen - 4 - 2 - 2]; + this.dataInputStream_.read(buf); + + // System.out.println("message: " + this.parser_.parseMsg(buf)); + + byte delim = 0; + ByteTokenizer bt = new ByteTokenizer(buf, delim); + + // "user" string + bt.nexToken(); + this.username_ = this.parser_.parseMsg(bt.nexToken()); + // "database" string + bt.nexToken(); + this.dbName_ = this.parser_.parseMsg(bt.nexToken()); + // from now on useless things like timezone, to print uncomment + // the + // following lines + // while (bt.hasMoreTokens()) + // System.out.println(this.parser_.parseMsg(bt.nexToken())); + return true; + } + } catch (Exception e) { + System.out.println("Error in receiveAuthMessage: "); + e.printStackTrace(); + return false; + } + } + + /** + * + * @return + */ + public char getMessageType() { + try { + return (char) this.dataInputStream_.readByte(); + } catch (Exception e) { + } + return 'e'; + } + + /** + * + * @return + */ + public String readParseMessage() { + try { + int msgLength = this.dataInputStream_.readInt(); + // - 4 for the message lenght + byte[] buf = new byte[msgLength - 4]; + if (this.dataInputStream_.read(buf) > 0) { + byte delim = '\0'; + ByteTokenizer bt = new ByteTokenizer(buf, delim); + + // from now on useless things like timezone, to print comment + // out + // following lines + try { + return this.parser_.parseMsg(bt.nexToken()); + } catch (Exception e) { + } + } + return "no query"; + } catch (IOException e) { + System.out.println("Error in readParseMessage: "); + e.printStackTrace(); + return null; + } + } + + private class MsgParser { + public short parseShort(byte[] bytes) { + byte[] typeBytes = new byte[2]; + typeBytes[0] = 0; + typeBytes[1] = bytes[0]; + return ByteBuffer.wrap(typeBytes).getShort(); + + } + + public int parseInt(byte[] bytes) { + byte[] lenBytes = Arrays.copyOf(bytes, 4); + int len = ByteBuffer.wrap(lenBytes).getInt(); + return len; + } + + public String parseMsg(byte[] bytes) + throws UnsupportedEncodingException { + String msgString = new String(bytes, "UTF-8"); + return msgString; + } + } +} diff --git a/src/com/etk/network/server/Sender.java b/src/com/etk/network/server/Sender.java index caaf393..74a1a9c 100644 --- a/src/com/etk/network/server/Sender.java +++ b/src/com/etk/network/server/Sender.java @@ -2,17 +2,38 @@ import java.io.DataOutputStream; import java.io.IOException; +import java.util.ArrayList; import java.util.LinkedList; import java.util.List; +import com.etk.db.query.QueryResult; +import com.etk.manager.schema.Type; + + public class Sender { + public static enum AuthEnum { + AuthOK, KerberosV5Required, ClearTextPasswordRequired, MD5EncryptedPasswordRequired + } + private DataOutputStream dataOutputStream_; public Sender(DataOutputStream output) { this.dataOutputStream_ = output; } + /** + * + */ + public void sendWeDontManageSSL() { + try { + this.dataOutputStream_.writeByte('N'); + } catch (IOException e) { + System.out.println("Error in sendParseCompleteMessage: "); + e.printStackTrace(); + } + } + /** * */ @@ -26,7 +47,7 @@ public void sendParseCompleteMessage() { } } - + /** * send an error message to the client * @@ -42,13 +63,17 @@ public void sendErrorResponse(String error) { // http://www.postgresql.org/docs/9.3/static/protocol-error-fields.html this.dataOutputStream_.writeByte('S'); this.dataOutputStream_.write(temp); + // an error message is always followed by a "ready for query" + // message. I put the call to this method here so we can manage the + // sendErrorResponse method "transparently" + this.sendReadyForQueryMessage(); } catch (IOException e) { System.out.println("Error in sendErrorResponse: "); e.printStackTrace(); } } - + /** * */ @@ -235,7 +260,7 @@ private byte[] nullTerminateString(String string) { for (int i = 0; i < in.length; i++) { out[i] = in[i]; } - out[in.length] = 0; + out[in.length] = '\0'; return out; } @@ -247,10 +272,7 @@ public void sendServerVersionMessage() { String param = "server_version"; String paramV = "9"; - byte[] nameB = nullTerminateString(param); // PEACE OF SHIT NEEDS TO - // BE - // NULTERMINATED EVEN THOUGH DOCS - // DONT MENTION IT + byte[] nameB = nullTerminateString(param); byte[] valB = nullTerminateString(paramV); this.dataOutputStream_.writeByte('S'); @@ -271,7 +293,6 @@ public void sendReadyForQueryMessage() { try { this.dataOutputStream_.writeByte('Z'); this.dataOutputStream_.writeInt(5); - this.dataOutputStream_.writeByte('I'); } catch (IOException e) { System.out.println("Error in sendReadyForQueryMessage: "); @@ -279,6 +300,82 @@ public void sendReadyForQueryMessage() { } } + /** + * + * @param row + */ + public void sendRowDescription(QueryResult row) { + try { + short fieldsNo = (short) row.getAttributes().length; + LinkedList bNameList = new LinkedList(); + // If the field can be identified as a column of a specific table, + // the + // object ID of the table; otherwise zero. + int identificator = 0; + // If the field can be identified as a column of a specific table, + // the + // attribute number of the column; otherwise zero. + short identificatorAtr = 0; + // The object ID of the field's data type. + List typeIndList = new ArrayList(); + // The type modifier (see pg_attribute.atttypmod). The meaning of + // the + // modifier is type-specific. + int typeMod = -1; + // The format code being used for the field. Currently will be zero + // (text) or one (binary). In a RowDescription returned from the + // statement variant of Describe, the format code is not yet known + // and + // will always be zero. + short formatCode = 0; + + int totalSize = 6; + + // Null terminate all column names + for (int i = 0; i < row.getAttributeTypes().length; i++) { + typeIndList.add(row.getAttributeTypes()[i]); + byte[] bName = nullTerminateString(row.getAttributes()[i]); + bNameList.add(bName); + totalSize += bName.length; + } + + totalSize += 18 * row.getAttributeTypes().length; + + this.dataOutputStream_.writeByte('T'); + this.dataOutputStream_.writeInt(totalSize); + this.dataOutputStream_.writeShort(fieldsNo); + + short typeLen = 0; + int typeInd = 0; + for (int i = 0; i < row.getAttributeTypes().length; i++) { + this.dataOutputStream_.writeBytes(new String(bNameList.get(i))); + this.dataOutputStream_.writeInt(identificator); + this.dataOutputStream_.writeShort(identificatorAtr); + switch (typeIndList.get(i)) { + case STRING: + typeLen = -1; + typeInd = 25; + break; + case INT: + typeLen = 4; + typeInd = 23; + break; + case REAL: + typeLen = 4; + typeInd = 23; + break; + } + this.dataOutputStream_.writeInt(typeInd); + this.dataOutputStream_.writeShort(typeLen); + this.dataOutputStream_.writeInt(typeMod); + this.dataOutputStream_.writeShort(formatCode); + } + } catch (IOException e) { + System.out.println("Error in sendRowDescription: "); + e.printStackTrace(); + } + } + /** * * @param columns @@ -312,23 +409,17 @@ public void sendRowDescription(String[] columns) { // will always be zero. short formatCode = 0; + int totalSize = 6; + // Null terminate all column names for (int i = 0; i < columns.length; i++) { String name = columns[i]; byte[] bName = nullTerminateString(name); bNameList.add(bName); + totalSize += bName.length; } - // FIXME: Why 8 and not 6? - int totalSize = 8; - - // calculate lenght of the of the message - for (int i = 0; i < columns.length; i++) { - totalSize += bNameList.get(i).length; - } - - // FIXME: Why 14 and not 18? - totalSize = totalSize + 14 * columns.length; + totalSize += 18 * columns.length; this.dataOutputStream_.writeByte('T'); this.dataOutputStream_.writeInt(totalSize); @@ -367,24 +458,24 @@ public void sendCommandCompleteMessage() { /** * - * @param list + * @param values */ - public void sendDataRow(List list) { + public void sendDataRow(String[] values) { try { // 4 bytes to communicate the lenght of the message + 2 bytes for // the // column numbers = 6 int tLen = 6; - short num = (short) list.size(); + short num = (short) values.length; LinkedList lenColList = new LinkedList(); LinkedList bvalList = new LinkedList(); byte[] val; // Sum the length of the column value - for (int i = 0; i < list.size(); i++) { - val = nullTerminateString(list.get(i)); + for (int i = 0; i < values.length; i++) { + val = values[i].getBytes(); lenColList.add(val.length); - bvalList.add(val); + bvalList.add(values[i].getBytes()); // lenght of the value + 4 bytes to communicate the value lenght tLen += val.length + 4; } @@ -395,16 +486,58 @@ public void sendDataRow(List list) { // for each value, send 4 bytes for the value lenght and n bytes for // the value itself - for (int i = 0; i < list.size(); i++) { + for (int i = 0; i < values.length; i++) { this.dataOutputStream_.writeInt(lenColList.get(i)); + this.dataOutputStream_.writeBytes(values[i]); + } + } catch (IOException e) { + System.out.println("Error in sendDataRow: "); + e.printStackTrace(); + } + } - this.dataOutputStream_.writeBytes(new String( - nullTerminateString(list.get(i)))); + public void sendDataRow(QueryResult row) { + try { + // 4 bytes to communicate the lenght of the message + 2 bytes for + // the + // column numbers = 6 + for (int i = 0; i < row.getData().size(); i++) { + + int tLen = 6; + short num = (short) row.getData().get(i).length; + LinkedList lenColList = new LinkedList(); + LinkedList bvalList = new LinkedList(); + byte[] val; + + // Sum the length of the column value + for (int j = 0; j < row.getData().get(i).length; j++) { + val = row.getData().get(i)[j].getBytes(); + lenColList.add(val.length); + bvalList.add(row.getData().get(i)[j].getBytes()); + // lenght of the value + 4 bytes to communicate the value + // lenght + tLen += val.length + 4; + } + + this.dataOutputStream_.writeByte('D'); + this.dataOutputStream_.writeInt(tLen); + this.dataOutputStream_.writeShort(num); + + // for each value, send 4 bytes for the value lenght and n bytes + // for + // the value itself + for (int j = 0; j < row.getData().get(i).length; j++) { + this.dataOutputStream_.writeInt(lenColList.get(j)); + + this.dataOutputStream_.writeBytes(new String( + nullTerminateString(row.getData().get(i)[j]))); + } } } catch (IOException e) { System.out.println("Error in sendDataRow: "); e.printStackTrace(); } + } /** @@ -421,12 +554,33 @@ public void flush() { /** * + * @param authMessage */ - public void sendAuthenticationOkMessage() { + public void sendAuthenticationOkMessage(AuthEnum authMessage) { try { this.dataOutputStream_.writeByte('R'); - this.dataOutputStream_.writeInt(8); - this.dataOutputStream_.writeInt(0); + switch (authMessage) { + case AuthOK: + this.dataOutputStream_.writeInt(8); + this.dataOutputStream_.writeInt(0); + break; + case KerberosV5Required: + this.dataOutputStream_.writeInt(8); + this.dataOutputStream_.writeInt(2); + break; + case ClearTextPasswordRequired: + this.dataOutputStream_.writeInt(8); + this.dataOutputStream_.writeInt(3); + break; + case MD5EncryptedPasswordRequired: + /* + * needs to implement a salt for the password, we can use + * something like: final Random r = new SecureRandom(); byte[] + * salt = new byte[4]; r.nextBytes(salt); // String encodedSalt + * = Base64.encodeBase64String(salt); + */ + throw new IllegalStateException(); + } } catch (IOException e) { System.out.println("Error in sendAuthenticationOkMessage: "); e.printStackTrace(); diff --git a/src/com/etk/network/server/SessionHandler.java b/src/com/etk/network/server/SessionHandler.java index e022365..c59b9da 100644 --- a/src/com/etk/network/server/SessionHandler.java +++ b/src/com/etk/network/server/SessionHandler.java @@ -1,417 +1,129 @@ -package com.etk.network.server; - -import java.io.*; -import java.net.Socket; -import java.nio.ByteBuffer; -import java.util.Arrays; - -import com.etk.parser.ProjectionCell; -import com.etk.parser.SelectObject; -import com.etk.parser.SelectQueryToObject; - -class SessionHandler implements Runnable { - private Socket server_; - private String line_, input_; - - SessionHandler(Socket server) { - this.server_ = server; - } - - private byte[] nullTerminateString(String string) { - byte[] in = string.getBytes(); - byte[] out = new byte[in.length + 1]; - for (int i = 0; i < in.length; i++) { - out[i] = in[i]; - } - out[in.length] = 0; - return out; - } - - private void sendServerVersionMessage(DataOutputStream dataOutputStream) - throws IOException { - String param = "server_version"; - String paramV = "9"; - - byte[] nameB = nullTerminateString(param); // PEACE OF SHIT NEEDS TO BE - // NULTERMINATED EVEN THOUGH DOCS - // DONT MENTION IT - byte[] valB = nullTerminateString(paramV); - - dataOutputStream.writeByte('S'); - dataOutputStream.writeInt(4 + nameB.length + valB.length); - dataOutputStream.write(nameB); - dataOutputStream.write(valB); - } - - private void sendAuthenticationOkMessage(DataOutputStream dataOutputStream) - throws IOException { - dataOutputStream.writeByte('R'); - dataOutputStream.writeInt(8); - dataOutputStream.writeInt(0); - } - - private void sendReadyForQueryMessage(DataOutputStream dataOutputStream) - throws IOException { - dataOutputStream.writeByte('Z'); - dataOutputStream.writeInt(5); - dataOutputStream.writeByte('I'); - } - - private void sendTerminateMessage(DataOutputStream dataOutputStream) - throws IOException { - dataOutputStream.writeByte('X'); - dataOutputStream.writeInt(4); - } - - private void sendCommandCompleteMessage(DataOutputStream dataOutputStream) - throws IOException { - dataOutputStream.writeByte('C'); - String tmp = "SELECT 1"; - dataOutputStream.writeInt(4 + tmp.getBytes().length); - dataOutputStream.write(tmp.getBytes()); - } - - private void sendParseCompleteMessage(DataOutputStream dataOutputStream) - throws IOException { - dataOutputStream.writeByte('1'); - dataOutputStream.writeInt(4); - } - - private void sendBindCompleteMessage(DataOutputStream dataOutputStream) - throws IOException { - dataOutputStream.writeByte('2'); - dataOutputStream.writeInt(4); - } - - private void sendEmptyQueryResponseMessage(DataOutputStream dataOutputStream) - throws IOException { - dataOutputStream.writeByte('I'); - dataOutputStream.writeInt(4); - } - - private void sendRowDescriptionMessage(DataOutputStream dataOutputStream) - throws IOException { - dataOutputStream.writeByte('T'); - dataOutputStream.writeInt(27); - dataOutputStream.writeShort(1); - dataOutputStream.writeBytes("id"); - dataOutputStream.writeInt(32780); - dataOutputStream.writeShort(3); - dataOutputStream.writeInt(20); - dataOutputStream.writeShort(8); - dataOutputStream.writeInt(-1); - dataOutputStream.writeShort(0); - - } - - /* Data row incorrect, needs to be finished */ - - private void sendDataRowMessage(DataOutputStream dataOutputStream) { - try { - dataOutputStream.writeByte('D'); - // Problem with upper line, after that it brokes (tried with other - // types of write after it). Why? Problem of size? - // Tried wireshark, it sends ACK FIN - dataOutputStream.writeInt(11); - dataOutputStream.writeShort(1); - dataOutputStream.writeInt(1); - dataOutputStream.writeByte('1'); - } catch (IOException ioe) { - System.out.println(ioe); - } - } - - public void run() { - - input_ = ""; - - try { - DataInputStream dataInputStream = new DataInputStream( - server_.getInputStream()); - DataOutputStream dataOutputStream = new DataOutputStream( - server_.getOutputStream()); - - MsgParser msgParser = new MsgParser(); - - int msgLen = dataInputStream.readInt(); - short protocolMajorVersion = dataInputStream.readShort(); - short protocolMinorVersion = dataInputStream.readShort(); - - byte[] authParamsB = new byte[msgLen - 8]; // msglen - version and - // len - dataInputStream.read(authParamsB); - // String authParams = msgParser.parseMsg(authParamsB); - - System.out.println("Client connected!"); - // System.out.println("Msg len: " + msgLen); - System.out.println("Protocol: V" + protocolMajorVersion + "." - + protocolMinorVersion); - - // System.out.println("Auth params: " + authParams); - - sendAuthenticationOkMessage(dataOutputStream); - - /* - * os.writeByte('K'); os.writeInt(12); os.writeInt(2); - * os.writeInt(3); - */ - - this.sendServerVersionMessage(dataOutputStream); - - this.sendReadyForQueryMessage(dataOutputStream); - - dataOutputStream.flush(); - - /* - * I think now the client wants the result of the query - */ - - // if (dataInputStream.available() > 0) { - byte type = dataInputStream.readByte(); - int msgLength = dataInputStream.readInt(); - System.out.println("Message Type: " + (char) type); - System.out.println("Lenght: " + msgLength); - - byte[] buf = new byte[dataInputStream.available() - 4]; - dataInputStream.read(buf); - String inputString = msgParser.parseMsg(buf); - System.out.println(inputString); - InputStream is = new - ByteArrayInputStream(inputString.getBytes("UTF-8")); - - //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - //Actual parsing of query and creation of selectObject which contains the query data: - SelectQueryToObject selectQueryToObject = new SelectQueryToObject(is); - SelectObject selectObject = selectQueryToObject.getSelectObject(); - - - //just for understanding of how to use selectObject: - /* for(String noPrefColName : selectObject.getNoPrefColNames()){ - System.out.println("Column: " + noPrefColName); - } - */ - for(ProjectionCell prefColName : selectObject.getPrefColNames()){ - System.out.println("Prefixed column found \n prefix: " + prefColName.getPrefix() - + "\n column name: " + prefColName.getColumnName()); - } - - for(String tableName : selectObject.getTableNames()){ - System.out.println("Table: " + tableName); - } - - /* - * this is in case the server receive an empty query string and - * seems to work sendEmptyQueryResponseMessage(dataOutputStream); - * sendReadyForQueryMessage(dataOutputStream); - * dataOutputStream.flush(); - */ - - sendData(dataOutputStream); - dataOutputStream.flush(); - - sendCommandCompleteMessage(dataOutputStream); - sendReadyForQueryMessage(dataOutputStream); - dataOutputStream.flush(); - - // reply to the client msg, delete exit - // } - - } catch (IOException ioe) { - System.out.println("IOException on socket listen: " + ioe); - ioe.printStackTrace(); - } catch (Exception e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - } - - private void sendData(DataOutputStream dataOutputStream) throws IOException { - /* - * RowDescription (B) Byte1('T') Identifies the message as a row - * description. Int32 Length of message contents in bytes, including - * self. Int16 Specifies the number of fields in a row (may be zero). - * Then, for each field, there is the following: String The field name. - * Int32 If the field can be identified as a column of a specific table, - * the object ID of the table; otherwise zero. Int16 If the field can be - * identified as a column of a specific table, the attribute number of - * the column; otherwise zero. Int32 The object ID of the field's data - * type. Int16 The data type size (see pg_type.typlen). Note that - * negative values denote variable-width types. Int32 The type modifier - * (see pg_attribute.atttypmod). The meaning of the modifier is - * type-specific. Int16 The format code being used for the field. - * Currently will be zero (text) or one (binary). In a RowDescription - * returned from the statement variant of Describe, the format code is - * not yet known and will always be zero. - * - * SSLRequest (F) - */ - - short fieldsNo = 4; - - String name = "name"; - byte[] bName = nullTerminateString(name); - int identificator = 0; - short identificatorAtr = 0; - int typeInd = 0; - short typeLen = -2; - int typeMod = -1; - short formatCode = 0; - - String name2 = "surname"; - byte[] bName2 = nullTerminateString(name2); - int identificator2 = 0; - short identificatorAtr2 = 0; - int typeInd2 = 0; - short typeLen2 = -2; - int typeMod2 = -1; - short formatCode2 = 0; - - String name3 = "date"; - byte[] bName3 = nullTerminateString(name3); - int identificator3 = 0; - short identificatorAtr3 = 0; - int typeInd3 = 0; - short typeLen3 = -2; - int typeMod3 = -1; - short formatCode3 = 0; - - String name4 = "number"; - byte[] bName4 = nullTerminateString(name4); - int identificator4 = 0; - short identificatorAtr4 = 0; - int typeInd4 = 0; - short typeLen4 = -2; - int typeMod4 = -1; - short formatCode4 = 0; - - int totalSize = bName.length + 4 + 2 + 4 + 2 + 4 + 2 + 4 - + bName3.length + 4 + 2 + 4 + 2 + 2 + bName4.length + 4 + 2 + 4 - + 2 + 2; - - dataOutputStream.writeByte('T'); - dataOutputStream.writeInt(totalSize); - dataOutputStream.writeShort(fieldsNo); - - dataOutputStream.writeBytes(new String(bName)); - dataOutputStream.writeInt(identificator); - dataOutputStream.writeShort(identificatorAtr); - dataOutputStream.writeInt(typeInd); - dataOutputStream.writeShort(typeLen); - dataOutputStream.writeInt(typeMod); - dataOutputStream.writeShort(formatCode); - - dataOutputStream.writeBytes(new String(bName2)); - dataOutputStream.writeInt(identificator2); - dataOutputStream.writeShort(identificatorAtr2); - dataOutputStream.writeInt(typeInd2); - dataOutputStream.writeShort(typeLen2); - dataOutputStream.writeInt(typeMod2); - dataOutputStream.writeShort(formatCode2); - - dataOutputStream.writeBytes(new String(bName3)); - dataOutputStream.writeInt(identificator3); - dataOutputStream.writeShort(identificatorAtr3); - dataOutputStream.writeInt(typeInd3); - dataOutputStream.writeShort(typeLen3); - dataOutputStream.writeInt(typeMod3); - dataOutputStream.writeShort(formatCode3); - - dataOutputStream.writeBytes(new String(bName4)); - dataOutputStream.writeInt(identificator4); - dataOutputStream.writeShort(identificatorAtr4); - dataOutputStream.writeInt(typeInd4); - dataOutputStream.writeShort(typeLen4); - dataOutputStream.writeInt(typeMod4); - dataOutputStream.writeShort(formatCode4); - - /* - * Byte1('D') Identifies the message as a data row. - * - * Int32 Length of message contents in bytes, including self. - * - * Int16 The number of column values that follow (possibly zero). - * - * Next, the following pair of fields appear for each column: - * - * Int32 The length of the column value, in bytes (this count does not - * include itself). Can be zero. As a special case, -1 indicates a NULL - * column value. No value bytes follow in the NULL case. - * - * Byten The value of the column, in the format indicated by the - * associated format code. n is the above lengt - */ - - for ( int i = 0; i < 2; i++){ - - int tLen = 0; - short num = 4; - - String val = "david"; - int lenCol = nullTerminateString(val).length; - byte[] bval = nullTerminateString(val); - - String val2 = "riobo"; - int lenCol2 = nullTerminateString(val2).length; - byte[] bval2 = nullTerminateString(val2); - - String val3 = "1992-01-17"; - int lenCol3 = nullTerminateString(val3).length; - byte[] bval3 = nullTerminateString(val3); - - String val4 = "-87,61"; - int lenCol4 = nullTerminateString(val4).length; - byte[] bval4 = nullTerminateString(val4); - - tLen = 4 + 2 + 4 + bval.length + 4 + bval2.length + 4 + bval3.length - + 4 + bval4.length; - dataOutputStream.writeByte('D'); - dataOutputStream.writeInt(tLen); - dataOutputStream.writeShort(num); - - dataOutputStream.writeInt(lenCol); - dataOutputStream.writeBytes(new String(nullTerminateString(val))); - - dataOutputStream.writeInt(lenCol2); - dataOutputStream.writeBytes(new String(nullTerminateString(val2))); - - // Returns Bad value for type date : 1992-01-17 - - dataOutputStream.writeInt(lenCol3); - dataOutputStream.writeBytes(new String(nullTerminateString(val3))); - - // Returns Bad value for type date too - - dataOutputStream.writeInt(lenCol4); - dataOutputStream.writeBytes(new String(nullTerminateString(val4))); - - } - - dataOutputStream.flush(); - - } - - private class MsgParser { - - public short parseShort(byte[] bytes) { - byte[] typeBytes = new byte[2]; - typeBytes[0] = 0; - typeBytes[1] = bytes[0]; - return ByteBuffer.wrap(typeBytes).getShort(); - - } - - public int parseInt(byte[] bytes) { - byte[] lenBytes = Arrays.copyOf(bytes, 4); - int len = ByteBuffer.wrap(lenBytes).getInt(); - return len; - } - - public String parseMsg(byte[] bytes) - throws UnsupportedEncodingException { - String msgString = new String(bytes, "UTF-8"); - return msgString; - } - - } - -} +package com.etk.network.server; + +import java.io.ByteArrayInputStream; +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.net.Socket; +import java.util.List; + +import mock.MockSelectObject; +import mock.MockedSchema; + +import com.etk.db.DBMSExecutor; +import com.etk.db.QueryExecutorImpl; +import com.etk.db.query.QueryResult; +import com.etk.manager.User; +import com.etk.manager.schema.Schema; +import com.etk.parser.SelectObject; +import com.etk.parser.SelectQueryToObject; + +class SessionHandler implements Runnable { + private Socket server_; + private Sender sender_; + private Receiver receiver_; + + public SessionHandler(Socket server) { + this.server_ = server; + // this.dataInputStream_ = dataInputStream; + try { + this.sender_ = new Sender(new DataOutputStream( + server_.getOutputStream())); + this.receiver_ = new Receiver(new DataInputStream( + server_.getInputStream())); + } catch (IOException e) { + e.printStackTrace(); + } + } + + public void run() { + try { + this.receiver_.getMessageType(); + String query = this.receiver_.readParseMessage(); + query = query.substring(0, query.length()-1); + System.out.println(query); + // InputStream is = new + // ByteArrayInputStream(query.getBytes("UTF-8")); + // SelectQueryToObject transform = new SelectQueryToObject(is); + // SelectObject selectObject = transform.getSelectObject(); + + // InputStream is = new ByteArrayInputStream( + // inputString.getBytes("UTF-8")); + // SelectQueryToObject transform = new SelectQueryToObject(is); + // SelectObject selectObject = transform.getSelectObject(); + // + // System.out.println("Parser found tables: " + // + selectObject.getTableNames().toString() + // + "\nParser found columns: " + // + selectObject.getColumnNames().toString()); + + // SELECTMain.parse(is); + + /* + * this is in case the server receive an empty query string and + * seems to work sendEmptyQueryResponseMessage(dataOutputStream); + * sendReadyForQueryMessage(dataOutputStream); + * dataOutputStream.flush(); + */ + + //InputStream is = new ByteArrayInputStream(query.getBytes("UTF-8")); + //SelectQueryToObject selectQueryToObject = new SelectQueryToObject( + // is); + //SelectObject selectObject = selectQueryToObject.getSelectObject(); + + SelectObject selectObject = new MockSelectObject(); + + User user = new User("marko"); + Schema schema = new MockedSchema(user); + + DBMSExecutor qExec = new QueryExecutorImpl(schema); + + List queryResultList = qExec + .executeQuery(selectObject); + + // getColumnNames from parser + + // Type[] types = queryResultList.get(0).getAttributeTypes(); + // String[] columns = queryResultList.get(0).getAttributes(); + + // String[] columns = { "name", "surname" }; + this.sender_.sendRowDescription(queryResultList.get(0)); + + for (int i = 0; i < 14 ; i++) { + this.sender_.sendDataRow(queryResultList.get(0).getData() + .get(i)); + } + + // this.sender_.sendDataRow(queryResultList.get(0).getData().get(0)); + // this.sender_.sendDataRow(queryResultList.get(0).getData().get(1)); + // this.sender_.sendDataRow(queryResultList.get(0).getData().get(2)); + // this.sender_.sendDataRow(queryResultList.get(0).getData().get(3)); + // this.sender_.sendDataRow(queryResultList.get(0).getData().get(4)); + // this.sender_.sendDataRow(queryResultList.get(0).getData().get(5)); + // this.sender_.sendDataRow(queryResultList.get(0).getData().get(6)); + // this.sender_.sendDataRow(queryResultList.get(0).getData().get(7)); + + // for (int i = 0; i < queryResultList.size(); i++) { + // QueryResult queryResult = queryResultList.get(i); + // this.sender_.sendDataRow(queryResult.getAttributes()); + // this.sender_.flush(); + // } + + // List values = new ArrayList(); + // values.add("david"); + // values.add("riobo"); + // this.sender_.sendDataRow(values); + + this.sender_.sendCommandCompleteMessage(); + this.sender_.sendReadyForQueryMessage(); + this.sender_.flush(); + + SessionHandler sessionHandler = new SessionHandler(server_); + Thread session = new Thread(sessionHandler); + session.start(); + } catch (Exception e) { + e.printStackTrace(); + } + } +} diff --git a/src/com/etk/parser/SELECTBaseListener.java b/src/com/etk/parser/SELECTBaseListener.java index 6c6f868..8efff89 100644 --- a/src/com/etk/parser/SELECTBaseListener.java +++ b/src/com/etk/parser/SELECTBaseListener.java @@ -159,13 +159,11 @@ public class SELECTBaseListener implements SELECTListener { *

* The default implementation does nothing. */ - @Override public void enterBooleanPrimary(@NotNull SELECTParser.BooleanPrimaryContext ctx) { } /** * {@inheritDoc} *

* The default implementation does nothing. */ - @Override public void exitBooleanPrimary(@NotNull SELECTParser.BooleanPrimaryContext ctx) { } /** * {@inheritDoc} @@ -432,13 +430,11 @@ public class SELECTBaseListener implements SELECTListener { *

* The default implementation does nothing. */ - @Override public void enterColumnName(@NotNull SELECTParser.ColumnNameContext ctx) { } /** * {@inheritDoc} *

* The default implementation does nothing. */ - @Override public void exitColumnName(@NotNull SELECTParser.ColumnNameContext ctx) { } /** * {@inheritDoc} diff --git a/src/com/etk/parser/SELECTListener.java b/src/com/etk/parser/SELECTListener.java index 40816a2..fb8ff00 100644 --- a/src/com/etk/parser/SELECTListener.java +++ b/src/com/etk/parser/SELECTListener.java @@ -132,12 +132,10 @@ public interface SELECTListener extends ParseTreeListener { * Enter a parse tree produced by {@link SELECTParser#tablePrimaryAs}. * @param ctx the parse tree */ - void enterTablePrimaryAs(@NotNull SELECTParser.TablePrimaryAsContext ctx); /** * Exit a parse tree produced by {@link SELECTParser#tablePrimaryAs}. * @param ctx the parse tree */ - void exitTablePrimaryAs(@NotNull SELECTParser.TablePrimaryAsContext ctx); /** * Enter a parse tree produced by {@link SELECTParser#derivedColumnList}. diff --git a/src/com/etk/parser/SELECTMain.java b/src/com/etk/parser/SELECTMain.java new file mode 100644 index 0000000..90cf3ac --- /dev/null +++ b/src/com/etk/parser/SELECTMain.java @@ -0,0 +1,44 @@ +package com.etk.parser; + +import org.antlr.v4.runtime.ANTLRInputStream; +import org.antlr.v4.runtime.CommonTokenStream; +import org.antlr.v4.runtime.tree.ParseTree; +import org.antlr.v4.runtime.tree.ParseTreeWalker; + +import java.io.FileInputStream; +import java.io.InputStream; + +/** + * Created with IntelliJ IDEA. + * User: Georgy + * Date: 10.11.13 + * Time: 10:56 + * To change this template use File | Settings | File Templates. + */ +public class SELECTMain { + + + public static void parse(InputStream is) throws Exception { +// String inputFile = null; +// if ( args.length>0 ) inputFile = args[0]; +// InputStream is = System.in; +// if ( inputFile!=null ) { +// is = new FileInputStream(inputFile); +// } + ANTLRInputStream input = new ANTLRInputStream(is); + SELECTLexer lexer = new SELECTLexer(input); + CommonTokenStream tokens = new CommonTokenStream(lexer); + SELECTParser parser = new SELECTParser(tokens); + parser.setBuildParseTree(true); + ParseTree tree = parser.selectStmnt(); + + /* ParseTreeWalker walker = new ParseTreeWalker(); + XMLEmitter converter = new XMLEmitter(); + walker.walk(converter, tree); + System.out.println(converter.getXML(tree)); + */ + } + + + +} diff --git a/src/com/etk/parser/SELECTParser.java b/src/com/etk/parser/SELECTParser.java index 433ad94..37cf509 100644 --- a/src/com/etk/parser/SELECTParser.java +++ b/src/com/etk/parser/SELECTParser.java @@ -1103,11 +1103,9 @@ public BooleanPrimaryContext(ParserRuleContext parent, int invokingState) { @Override public int getRuleIndex() { return RULE_booleanPrimary; } @Override public void enterRule(ParseTreeListener listener) { - if ( listener instanceof SELECTListener ) ((SELECTListener)listener).enterBooleanPrimary(this); } @Override public void exitRule(ParseTreeListener listener) { - if ( listener instanceof SELECTListener ) ((SELECTListener)listener).exitBooleanPrimary(this); } }