Added pgSQL support
This commit is contained in:
		| @ -8,6 +8,7 @@ const output = path.resolve(__dirname, '../src/lib'); | ||||
| const entry = [ | ||||
|     'generic', | ||||
|     'hive', | ||||
|     'pgsql', | ||||
|     'plsql', | ||||
|     'spark', | ||||
|     'flinksql', | ||||
|  | ||||
| @ -32,7 +32,7 @@ | ||||
|     "eslint-config-google": "^0.14.0", | ||||
|     "jest": "^24.8.0", | ||||
|     "ts-jest": "^24.1.0", | ||||
|     "typescript": "^3.6.3", | ||||
|     "typescript": "^4.9.4", | ||||
|     "standard-version": "^9.1.0" | ||||
|   }, | ||||
|   "git repository": "https://github.com/DTStack/dt-sql-parser", | ||||
|  | ||||
							
								
								
									
										2544
									
								
								src/grammar/pgsql/PostgreSQLLexer.g4
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										2544
									
								
								src/grammar/pgsql/PostgreSQLLexer.g4
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										5327
									
								
								src/grammar/pgsql/PostgreSQLParser.g4
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										5327
									
								
								src/grammar/pgsql/PostgreSQLParser.g4
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										1702
									
								
								src/lib/pgsql/PostgreSQLLexer.interp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1702
									
								
								src/lib/pgsql/PostgreSQLLexer.interp
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
							
								
								
									
										4873
									
								
								src/lib/pgsql/PostgreSQLLexer.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										4873
									
								
								src/lib/pgsql/PostgreSQLLexer.js
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										1066
									
								
								src/lib/pgsql/PostgreSQLLexer.tokens
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1066
									
								
								src/lib/pgsql/PostgreSQLLexer.tokens
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										1925
									
								
								src/lib/pgsql/PostgreSQLParser.interp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1925
									
								
								src/lib/pgsql/PostgreSQLParser.interp
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
							
								
								
									
										129402
									
								
								src/lib/pgsql/PostgreSQLParser.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										129402
									
								
								src/lib/pgsql/PostgreSQLParser.js
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
							
								
								
									
										1066
									
								
								src/lib/pgsql/PostgreSQLParser.tokens
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1066
									
								
								src/lib/pgsql/PostgreSQLParser.tokens
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										7305
									
								
								src/lib/pgsql/PostgreSQLParserListener.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										7305
									
								
								src/lib/pgsql/PostgreSQLParserListener.js
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										4876
									
								
								src/lib/pgsql/PostgreSQLParserVisitor.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										4876
									
								
								src/lib/pgsql/PostgreSQLParserVisitor.js
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										55
									
								
								src/lib/pgsql/base/LexerDispatchingErrorListener.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										55
									
								
								src/lib/pgsql/base/LexerDispatchingErrorListener.java
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,55 @@ | ||||
| import java.util.BitSet; | ||||
| import org.antlr.v4.runtime.*; | ||||
| import org.antlr.v4.runtime.atn.*; | ||||
| import org.antlr.v4.runtime.dfa.*; | ||||
| import org.antlr.v4.runtime.misc.*; | ||||
|  | ||||
| public class LexerDispatchingErrorListener implements ANTLRErrorListener | ||||
| { | ||||
|     Lexer _parent; | ||||
|  | ||||
|     public LexerDispatchingErrorListener(Lexer parent) | ||||
|     { | ||||
|         _parent = parent; | ||||
|     } | ||||
|  | ||||
|     public void syntaxError(Recognizer<?, ?> recognizer, Object offendingSymbol, int line, int charPositionInLine, String msg, RecognitionException e) | ||||
|     { | ||||
|         var foo = new ProxyErrorListener(_parent.getErrorListeners()); | ||||
|         foo.syntaxError(recognizer, offendingSymbol, line, charPositionInLine, msg, e); | ||||
|     } | ||||
|  | ||||
|     public void reportAmbiguity(Parser recognizer, | ||||
|                                 DFA dfa, | ||||
|                                 int startIndex, | ||||
|                                 int stopIndex, | ||||
|                                 boolean exact, | ||||
|                                 BitSet ambigAlts, | ||||
|                                 ATNConfigSet configs) | ||||
|     { | ||||
|         var foo = new ProxyErrorListener(_parent.getErrorListeners()); | ||||
|         foo.reportAmbiguity(recognizer, dfa, startIndex, stopIndex, exact, ambigAlts, configs); | ||||
|     } | ||||
|  | ||||
|     public void reportAttemptingFullContext(Parser recognizer, | ||||
|                                             DFA dfa, | ||||
|                                             int startIndex, | ||||
|                                             int stopIndex, | ||||
|                                             BitSet conflictingAlts, | ||||
|                                             ATNConfigSet configs) | ||||
|     { | ||||
|         var foo = new ProxyErrorListener(_parent.getErrorListeners()); | ||||
|         foo.reportAttemptingFullContext(recognizer, dfa, startIndex, stopIndex, conflictingAlts, configs); | ||||
|     } | ||||
|  | ||||
|     public void reportContextSensitivity(Parser recognizer, | ||||
|                                          DFA dfa, | ||||
|                                          int startIndex, | ||||
|                                          int stopIndex, | ||||
|                                          int prediction, | ||||
|                                          ATNConfigSet configs) | ||||
|     { | ||||
|         var foo = new ProxyErrorListener(_parent.getErrorListeners()); | ||||
|         foo.reportContextSensitivity(recognizer, dfa, startIndex, stopIndex, prediction, configs); | ||||
|     } | ||||
| } | ||||
							
								
								
									
										55
									
								
								src/lib/pgsql/base/ParserDispatchingErrorListener.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										55
									
								
								src/lib/pgsql/base/ParserDispatchingErrorListener.java
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,55 @@ | ||||
| import java.util.BitSet; | ||||
| import org.antlr.v4.runtime.*; | ||||
| import org.antlr.v4.runtime.atn.*; | ||||
| import org.antlr.v4.runtime.dfa.*; | ||||
| import org.antlr.v4.runtime.misc.*; | ||||
|  | ||||
| public class ParserDispatchingErrorListener implements ANTLRErrorListener | ||||
| { | ||||
|     Parser _parent; | ||||
|  | ||||
|     public ParserDispatchingErrorListener(Parser parent) | ||||
|     { | ||||
|         _parent = parent; | ||||
|     } | ||||
|  | ||||
|     public void syntaxError(Recognizer<?, ?> recognizer, Object offendingSymbol, int line, int charPositionInLine, String msg, RecognitionException e) | ||||
|     { | ||||
|         var foo = new ProxyErrorListener(_parent.getErrorListeners()); | ||||
|         foo.syntaxError(recognizer, offendingSymbol, line, charPositionInLine, msg, e); | ||||
|     } | ||||
|  | ||||
|     public void reportAmbiguity(Parser recognizer, | ||||
|                                 DFA dfa, | ||||
|                                 int startIndex, | ||||
|                                 int stopIndex, | ||||
|                                 boolean exact, | ||||
|                                 BitSet ambigAlts, | ||||
|                                 ATNConfigSet configs) | ||||
|     { | ||||
|         var foo = new ProxyErrorListener(_parent.getErrorListeners()); | ||||
|         foo.reportAmbiguity(recognizer, dfa, startIndex, stopIndex, exact, ambigAlts, configs); | ||||
|     } | ||||
|  | ||||
|     public void reportAttemptingFullContext(Parser recognizer, | ||||
|                                             DFA dfa, | ||||
|                                             int startIndex, | ||||
|                                             int stopIndex, | ||||
|                                             BitSet conflictingAlts, | ||||
|                                             ATNConfigSet configs) | ||||
|     { | ||||
|         var foo = new ProxyErrorListener(_parent.getErrorListeners()); | ||||
|         foo.reportAttemptingFullContext(recognizer, dfa, startIndex, stopIndex, conflictingAlts, configs); | ||||
|     } | ||||
|  | ||||
|     public void reportContextSensitivity(Parser recognizer, | ||||
|                                          DFA dfa, | ||||
|                                          int startIndex, | ||||
|                                          int stopIndex, | ||||
|                                          int prediction, | ||||
|                                          ATNConfigSet configs) | ||||
|     { | ||||
|         var foo = new ProxyErrorListener(_parent.getErrorListeners()); | ||||
|         foo.reportContextSensitivity(recognizer, dfa, startIndex, stopIndex, prediction, configs); | ||||
|     } | ||||
| } | ||||
							
								
								
									
										67
									
								
								src/lib/pgsql/base/PostgreSQLLexerBase.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										67
									
								
								src/lib/pgsql/base/PostgreSQLLexerBase.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,67 @@ | ||||
| const antlr4 = require('antlr4/index'); | ||||
| const Lexer = antlr4.Lexer; | ||||
| function isLetter(str) { | ||||
|     return str.length === 1 && str.match(/[a-z]/i); | ||||
| } | ||||
| export class PostgreSQLLexerBase extends Lexer { | ||||
|     tags = []; | ||||
|  | ||||
|     constructor(input) { | ||||
|         super(input); | ||||
|     } | ||||
|  | ||||
|     pushTag() { | ||||
|         this.tags.push(getText()); | ||||
|     } | ||||
|  | ||||
|     isTag() { | ||||
|         return this.getText().equals(this.tags.peek()); | ||||
|     } | ||||
|  | ||||
|     popTag() { | ||||
|         tags.pop(); | ||||
|     } | ||||
|  | ||||
|     getInputStream() { | ||||
|         return this._input; | ||||
|     } | ||||
|     checkLA( c) { | ||||
|         // eslint-disable-next-line new-cap | ||||
|         return this.getInputStream().LA(1) !== c; | ||||
|     } | ||||
|  | ||||
|     charIsLetter() { | ||||
|         // eslint-disable-next-line new-cap | ||||
|         return isLetter(this.getInputStream().LA(-1)); | ||||
|     } | ||||
|  | ||||
|     HandleNumericFail() { | ||||
|         this.getInputStream().seek(this.getInputStream().index() - 2); | ||||
|         const Integral = 535; | ||||
|         this.setType(Integral); | ||||
|     } | ||||
|  | ||||
|     HandleLessLessGreaterGreater() { | ||||
|         const LESS_LESS = 18; | ||||
|         const GREATER_GREATER = 19; | ||||
|         if (this.getText() === '<<') this.setType(LESS_LESS); | ||||
|         if (this.getText() === '>>') this.setType(GREATER_GREATER); | ||||
|     } | ||||
|  | ||||
|     UnterminatedBlockCommentDebugAssert() { | ||||
|         // Debug.Assert(InputStream.LA(1) == -1 /*EOF*/); | ||||
|     } | ||||
|  | ||||
|     CheckIfUtf32Letter() { | ||||
|         // eslint-disable-next-line new-cap | ||||
|         let codePoint = this.getInputStream().LA(-2) << 8 + this.getInputStream().LA(-1); | ||||
|         let c; | ||||
|         if (codePoint < 0x10000) { | ||||
|             c = String.fromCharCode(codePoint); | ||||
|         } else { | ||||
|             codePoint -= 0x10000; | ||||
|             c = String.fromCharCode(codePoint / 0x400 + 0xd800, codePoint % 0x400 + 0xdc00); | ||||
|         } | ||||
|         return isLetter(c[0]); | ||||
|     } | ||||
| } | ||||
							
								
								
									
										114
									
								
								src/lib/pgsql/base/PostgreSQLParserBase.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										114
									
								
								src/lib/pgsql/base/PostgreSQLParserBase.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,114 @@ | ||||
| /* eslint-disable new-cap */ | ||||
| import { PostgreSQLLexer } from '../PostgreSQLLexer'; | ||||
| import { PostgreSQLParser } from '../PostgreSQLParser'; | ||||
|  | ||||
|  | ||||
| const antlr4 = require('antlr4/index'); | ||||
| const CharStreams = antlr4.CharStreams; | ||||
| const CommonTokenStream = antlr4.CommonTokenStream; | ||||
|  | ||||
|  | ||||
| // @ts-ignore | ||||
| export class PostgreSQLParserBase extends antlr4.Parser { | ||||
|     constructor( input) { | ||||
|         super(input); | ||||
|     } | ||||
|  | ||||
|     GetParsedSqlTree( script, line) { | ||||
|         const ph = this.getPostgreSQLParser(script); | ||||
|         return ph.root(); | ||||
|     } | ||||
|  | ||||
|     ParseRoutineBody( _localctx) { | ||||
|         let lang = null; | ||||
|         for (const coi of _localctx.createfunc_opt_item()) { | ||||
|             // eslint-disable-next-line new-cap | ||||
|             if (!coi.LANGUAGE()) { | ||||
|                 if (!coi.nonreservedword_or_sconst()) { | ||||
|                     if (!coi.nonreservedword_or_sconst().nonreservedword()) { | ||||
|                         if (!coi.nonreservedword_or_sconst().nonreservedword().identifier()) { | ||||
|                             // eslint-disable-next-line new-cap | ||||
|                             if (!coi.nonreservedword_or_sconst().nonreservedword().identifier().Identifier()) { | ||||
|                                 // eslint-disable-next-line new-cap | ||||
|                                 lang = coi.nonreservedword_or_sconst().nonreservedword().identifier().Identifier().getText(); | ||||
|                                 break; | ||||
|                             } | ||||
|                         } | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|         if (!lang) return; | ||||
|         // eslint-disable-next-line camelcase | ||||
|         let func_as = null; | ||||
|         for (const a of _localctx.createfunc_opt_item()) { | ||||
|             if (!a.func_as()) { | ||||
|                 // eslint-disable-next-line camelcase | ||||
|                 func_as = a; | ||||
|                 break; | ||||
|             } | ||||
|         } | ||||
|         // eslint-disable-next-line camelcase | ||||
|         if (!func_as) { | ||||
|             const txt = this.GetRoutineBodyString(func_as.func_as().sconst(0)); | ||||
|             const line = func_as.func_as().sconst(0).start.getLine(); | ||||
|             const ph = this.getPostgreSQLParser(txt); | ||||
|             switch (lang) { | ||||
|             case 'plpgsql': | ||||
|                 func_as.func_as().Definition = ph.plsqlroot(); | ||||
|                 break; | ||||
|             case 'sql': | ||||
|                 func_as.func_as().Definition = ph.root(); | ||||
|                 break; | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     TrimQuotes( s) { | ||||
|         return (!s) ? s : s.substring(1, s.length() - 1); | ||||
|     } | ||||
|  | ||||
|     unquote( s) { | ||||
|         const slength = s.length(); | ||||
|         const r = ''; | ||||
|         let i = 0; | ||||
|         while (i < slength) { | ||||
|             const c = s.charAt(i); | ||||
|             r.append(c); | ||||
|             if (c === '\'' && i < slength - 1 && (s.charAt(i + 1) === '\'')) i++; | ||||
|             i++; | ||||
|         } | ||||
|         return r.toString(); | ||||
|     } | ||||
|  | ||||
|     GetRoutineBodyString( rule) { | ||||
|         const anysconst = rule.anysconst(); | ||||
|         // eslint-disable-next-line new-cap | ||||
|         const StringConstant = anysconst.StringConstant(); | ||||
|         if (null !== StringConstant) return this.unquote(this.TrimQuotes(StringConstant.getText())); | ||||
|         const UnicodeEscapeStringConstant = anysconst.UnicodeEscapeStringConstant(); | ||||
|         if (null !== UnicodeEscapeStringConstant) return this.TrimQuotes(UnicodeEscapeStringConstant.getText()); | ||||
|         const EscapeStringConstant = anysconst.EscapeStringConstant(); | ||||
|         if (null !== EscapeStringConstant) return this.TrimQuotes(EscapeStringConstant.getText()); | ||||
|         let result = ''; | ||||
|         const dollartext = anysconst.DollarText(); | ||||
|         for (const s of dollartext) { | ||||
|             result += s.getText(); | ||||
|         } | ||||
|         return result; | ||||
|     } | ||||
|  | ||||
|     static getPostgreSQLParser( script) { | ||||
|         const charStream = CharStreams.fromString(script); | ||||
|         const lexer = new PostgreSQLLexer(charStream); | ||||
|         const tokens = new CommonTokenStream(lexer); | ||||
|         const parser = new PostgreSQLParser(tokens); | ||||
|         lexer.removeErrorListeners(); | ||||
|         parser.removeErrorListeners(); | ||||
|         //  LexerDispatchingErrorListener listener_lexer = new LexerDispatchingErrorListener((Lexer)(((CommonTokenStream)(this.getInputStream())).getTokenSource())); | ||||
|         //   ParserDispatchingErrorListener listener_parser = new ParserDispatchingErrorListener(this); | ||||
|         //   lexer.addErrorListener(listener_lexer); | ||||
|         //  parser.addErrorListener(listener_parser); | ||||
|         return parser; | ||||
|     } | ||||
| } | ||||
| @ -23,7 +23,8 @@ export default abstract class BasicParser<C = any> { | ||||
|         parser.removeErrorListeners(); | ||||
|         parser.addErrorListener(new ParserErrorListener(errorListener)); | ||||
|  | ||||
|         const parserTree = parser.program(); | ||||
|         // Note :  needed by pgsql | ||||
|         const parserTree = parser.program? parser.program() : parser.root(); | ||||
|  | ||||
|         return parserTree; | ||||
|     } | ||||
| @ -37,7 +38,12 @@ export default abstract class BasicParser<C = any> { | ||||
|         parser.removeErrorListeners(); | ||||
|         parser.addErrorListener(new ParserErrorCollector(syntaxErrors)); | ||||
|  | ||||
|         parser.program(); | ||||
|         // Note :  needed by pgsql | ||||
|         if (parser.program) { | ||||
|             parser.program(); | ||||
|         } else { | ||||
|             parser.root(); | ||||
|         } | ||||
|  | ||||
|         return lexerError.concat(syntaxErrors); | ||||
|     } | ||||
| @ -89,7 +95,8 @@ export default abstract class BasicParser<C = any> { | ||||
|         const parser = this.createParser(input); | ||||
|         this._parser = parser; | ||||
|  | ||||
|         const tree = parser.program(); | ||||
|         // Note :  needed by pgsql | ||||
|         const tree = parser.program? parser.program() : parser.root(); | ||||
|         return tree.toStringTree(parser.ruleNames); | ||||
|     } | ||||
|  | ||||
|  | ||||
							
								
								
									
										17
									
								
								src/parser/pgsql.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								src/parser/pgsql.ts
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,17 @@ | ||||
| import { InputStream, CommonTokenStream, Lexer } from 'antlr4'; | ||||
| import { PostgreSQLLexer } from '../lib/pgsql/PostgreSQLLexer'; | ||||
| import { PostgreSQLParser } from '../lib/pgsql/PostgreSQLParser'; | ||||
|  | ||||
| import BasicParser from './common/basicParser'; | ||||
|  | ||||
| export default class PLSQLParser extends BasicParser { | ||||
|     public createLexer(input: string): Lexer { | ||||
|         const chars = new InputStream(input.toUpperCase()); | ||||
|         const lexer = <unknown> new PostgreSQLLexer(chars) as Lexer; | ||||
|         return lexer; | ||||
|     } | ||||
|     public createParserFromLexer(lexer: Lexer): any { | ||||
|         const tokenStream = new CommonTokenStream(lexer); | ||||
|         return new PostgreSQLParser(tokenStream); | ||||
|     } | ||||
| } | ||||
| @ -3,7 +3,7 @@ | ||||
|         "outDir": "./dist/", | ||||
|         "sourceMap": true, | ||||
|         "allowJs":true, | ||||
|         "target": "es6", | ||||
|         "target": "es5", | ||||
|         "module": "commonjs", | ||||
|         "declaration": true, | ||||
|         "noUnusedLocals": true, | ||||
|  | ||||
		Reference in New Issue
	
	Block a user