/******************************************************************************* | |
* Copyright (c) 2011 Oracle. All rights reserved. | |
* This program and the accompanying materials are made available under the | |
* terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0 | |
* which accompanies this distribution. | |
* The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html | |
* and the Eclipse Distribution License is available at | |
* http://www.eclipse.org/org/documents/edl-v10.php. | |
* | |
* Contributors: | |
* Mike Norman - June 10 2011, created DDL parser package | |
******************************************************************************/ | |
options { | |
STATIC = false; | |
SUPPORT_CLASS_VISIBILITY_PUBLIC = true; | |
ERROR_REPORTING = false; | |
JAVA_UNICODE_ESCAPE = true; | |
UNICODE_INPUT = true; | |
NODE_USES_PARSER = false; | |
NODE_DEFAULT_VOID = true; | |
VISITOR = true; | |
} | |
PARSER_BEGIN(DDLParser) | |
/******************************************************************************* | |
* Copyright (c) 2011 Oracle. All rights reserved. | |
* This program and the accompanying materials are made available under the | |
* terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0 | |
* which accompanies this distribution. | |
* The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html | |
* and the Eclipse Distribution License is available at | |
* http://www.eclipse.org/org/documents/edl-v10.php. | |
* | |
* Contributors: | |
* Mike Norman - June 10 2011, created DDL parser package | |
******************************************************************************/ | |
package org.eclipse.persistence.tools.oracleddl.parser; | |
//javase imports | |
import java.io.InputStream; | |
import java.util.List; | |
import java.util.HashMap; | |
import java.util.Map; | |
//metadata imports | |
import org.eclipse.persistence.tools.oracleddl.metadata.ArgumentType; | |
import org.eclipse.persistence.tools.oracleddl.metadata.ArgumentTypeDirection; | |
import org.eclipse.persistence.tools.oracleddl.metadata.BlobType; | |
import org.eclipse.persistence.tools.oracleddl.metadata.CharType; | |
import org.eclipse.persistence.tools.oracleddl.metadata.ClobType; | |
import org.eclipse.persistence.tools.oracleddl.metadata.CompositeDatabaseType; | |
import org.eclipse.persistence.tools.oracleddl.metadata.DatabaseType; | |
import org.eclipse.persistence.tools.oracleddl.metadata.DecimalType; | |
import org.eclipse.persistence.tools.oracleddl.metadata.DoubleType; | |
import org.eclipse.persistence.tools.oracleddl.metadata.FieldType; | |
import org.eclipse.persistence.tools.oracleddl.metadata.FloatType; | |
import org.eclipse.persistence.tools.oracleddl.metadata.FunctionType; | |
import org.eclipse.persistence.tools.oracleddl.metadata.IntervalDayToSecond; | |
import org.eclipse.persistence.tools.oracleddl.metadata.IntervalYearToMonth; | |
import org.eclipse.persistence.tools.oracleddl.metadata.LongType; | |
import org.eclipse.persistence.tools.oracleddl.metadata.LongRawType; | |
import org.eclipse.persistence.tools.oracleddl.metadata.NCharType; | |
import org.eclipse.persistence.tools.oracleddl.metadata.NClobType; | |
import org.eclipse.persistence.tools.oracleddl.metadata.NumericType; | |
import org.eclipse.persistence.tools.oracleddl.metadata.NVarChar2Type; | |
import org.eclipse.persistence.tools.oracleddl.metadata.ObjectType; | |
import org.eclipse.persistence.tools.oracleddl.metadata.ObjectTableType; | |
import org.eclipse.persistence.tools.oracleddl.metadata.PLSQLCollectionType; | |
import org.eclipse.persistence.tools.oracleddl.metadata.PLSQLCursorType; | |
import org.eclipse.persistence.tools.oracleddl.metadata.PLSQLPackageType; | |
import org.eclipse.persistence.tools.oracleddl.metadata.PLSQLRecordType; | |
import org.eclipse.persistence.tools.oracleddl.metadata.PLSQLType; | |
import org.eclipse.persistence.tools.oracleddl.metadata.PLSQLSubType; | |
import org.eclipse.persistence.tools.oracleddl.metadata.ProcedureType; | |
import org.eclipse.persistence.tools.oracleddl.metadata.RawType; | |
import org.eclipse.persistence.tools.oracleddl.metadata.RealType; | |
import org.eclipse.persistence.tools.oracleddl.metadata.TableType; | |
import org.eclipse.persistence.tools.oracleddl.metadata.TimeStampType; | |
import org.eclipse.persistence.tools.oracleddl.metadata.URowIdType; | |
import org.eclipse.persistence.tools.oracleddl.metadata.UnresolvedSizedType; | |
import org.eclipse.persistence.tools.oracleddl.metadata.UnresolvedType; | |
import org.eclipse.persistence.tools.oracleddl.metadata.VarCharType; | |
import org.eclipse.persistence.tools.oracleddl.metadata.VarChar2Type; | |
import org.eclipse.persistence.tools.oracleddl.metadata.VArrayType; | |
import org.eclipse.persistence.tools.oracleddl.util.DatabaseTypesRepository; | |
import static org.eclipse.persistence.tools.oracleddl.metadata.ScalarDatabaseTypeEnum.BFILE_TYPE; | |
import static org.eclipse.persistence.tools.oracleddl.metadata.ScalarDatabaseTypeEnum.BINARY_INTEGER_TYPE; | |
import static org.eclipse.persistence.tools.oracleddl.metadata.ScalarDatabaseTypeEnum.BINARY_FLOAT_TYPE; | |
import static org.eclipse.persistence.tools.oracleddl.metadata.ScalarDatabaseTypeEnum.BINARY_DOUBLE_TYPE; | |
import static org.eclipse.persistence.tools.oracleddl.metadata.ScalarDatabaseTypeEnum.BOOLEAN_TYPE; | |
import static org.eclipse.persistence.tools.oracleddl.metadata.ScalarDatabaseTypeEnum.DATE_TYPE; | |
import static org.eclipse.persistence.tools.oracleddl.metadata.ScalarDatabaseTypeEnum.INTEGER_TYPE; | |
import static org.eclipse.persistence.tools.oracleddl.metadata.ScalarDatabaseTypeEnum.MLSLABEL_TYPE; | |
import static org.eclipse.persistence.tools.oracleddl.metadata.ScalarDatabaseTypeEnum.NATURAL_TYPE; | |
import static org.eclipse.persistence.tools.oracleddl.metadata.ScalarDatabaseTypeEnum.PLS_INTEGER_TYPE; | |
import static org.eclipse.persistence.tools.oracleddl.metadata.ScalarDatabaseTypeEnum.POSITIVE_TYPE; | |
import static org.eclipse.persistence.tools.oracleddl.metadata.ScalarDatabaseTypeEnum.ROWID_TYPE; | |
import static org.eclipse.persistence.tools.oracleddl.metadata.ScalarDatabaseTypeEnum.SIGN_TYPE; | |
import static org.eclipse.persistence.tools.oracleddl.metadata.ScalarDatabaseTypeEnum.SIMPLE_INTEGER_TYPE; | |
import static org.eclipse.persistence.tools.oracleddl.metadata.ScalarDatabaseTypeEnum.SIMPLE_DOUBLE_TYPE; | |
import static org.eclipse.persistence.tools.oracleddl.metadata.ScalarDatabaseTypeEnum.SIMPLE_FLOAT_TYPE; | |
import static org.eclipse.persistence.tools.oracleddl.metadata.ScalarDatabaseTypeEnum.SMALLINT_TYPE; | |
import static org.eclipse.persistence.tools.oracleddl.metadata.ScalarDatabaseTypeEnum.SYS_REFCURSOR_TYPE; | |
import static org.eclipse.persistence.tools.oracleddl.metadata.ScalarDatabaseTypeEnum.TIME_TYPE; | |
public class DDLParser { | |
protected Map<String, DatabaseType> localTypes = new HashMap<String, DatabaseType>(); | |
protected DatabaseTypesRepository typesRepository = new DatabaseTypesRepository(); | |
public DDLParser() { | |
super(); | |
} | |
public void setTypesRepository(DatabaseTypesRepository typesRepository) { | |
this.typesRepository = typesRepository; | |
} | |
public DatabaseTypesRepository getTypesRepository() { | |
return typesRepository; | |
} | |
} | |
PARSER_END(DDLParser) | |
// white-space | |
SKIP: { | |
" " | |
| "\t" | |
| "\n" | |
| "\r" | |
| "\f" | |
} | |
// comments | |
SKIP: { | |
<COMMENT_LINE: "--" (~["\n","\r"])* ("\n"|"\r"|"\r\n") > | |
} | |
SKIP:{ | |
<COMMENT_BLOCK: "/*" (~["*"])* "*" ("*" | (~["*","/"] (~["*"])* "*"))* "/"> | |
} | |
// PLSQL reserved keywords (prefix with K_ to avoid naming conflicts) - NB: incomplete list | |
TOKEN [IGNORE_CASE]: { | |
<K_A: "A"> | |
| <K_ADD: "ADD"> | |
| <K_ALTER: "ALTER"> | |
| <K_ARRAY: "ARRAY"> | |
| <K_AS: "AS"> | |
| <K_AUTHID: "AUTHID"> | |
| <K_AUTOMATIC: "AUTOMATIC"> | |
| <K_AUTONOMOUS_TRANSACTION: "AUTONOMOUS_TRANSACTION"> | |
| <K_BEGIN: "BEGIN"> | |
| <K_BFILE: "BFILE"> | |
| <K_BINARY_DOUBLE: "BINARY_DOUBLE"> | |
| <K_BINARY_FLOAT: "BINARY_FLOAT"> | |
| <K_BINARY_INTEGER: "BINARY_INTEGER"> | |
| <K_BLOB: "BLOB"> | |
| <K_BODY: "BODY"> | |
| <K_BOOLEAN: "BOOLEAN"> | |
| <K_BUILTIN: "BUILTIN"> | |
| <K_BULK: "BULK"> | |
| <K_BY: "BY"> | |
| <K_BYTE: "BYTE"> | |
| <K_CHAR: "CHAR"> | |
| <K_CHARACTER: "CHARACTER"> | |
| <K_CHARSET: "%CHARSET"> | |
| <K_CLOB: "CLOB"> | |
| <K_CLOSE: "CLOSE"> | |
| <K_COLLECT: "COLLECT"> | |
| <K_COMMIT: "COMMIT"> | |
| <K_CONSTANT: "CONSTANT"> | |
| <K_CONSTRAINT: "CONSTRAINT"> | |
| <K_COUNT: "COUNT"> | |
| <K_CREATE: "CREATE"> | |
| <K_CROSS: "CROSS"> | |
| <K_CUBE: "CUBE"> | |
| <K_CURRENT_OF: "CURRENT_OF"> | |
| <K_CURRENT_USER: "CURRENT_USER"> | |
| <K_CURSOR: "CURSOR"> | |
| <K_DATE: "DATE"> | |
| <K_DAY: "DAY"> | |
| <K_DBTIMEZONE: "DBTIMEZONE"> | |
| <K_DEC: "DEC"> | |
| <K_DECIMAL: "DECIMAL"> | |
| <K_DECREMENT: "DECREMENT"> | |
| <K_DEFAULT: "DEFAULT"> | |
| <K_DEFINER: "DEFINER"> | |
| <K_DELETE: "DELETE"> | |
| <K_DETERMINISTIC: "DETERMINISTIC"> | |
| <K_DIMENSION: "DIMENSION"> | |
| <K_DOUBLE: "DOUBLE"> | |
| <K_ELSIF: "ELSIF"> | |
| <K_EMPTY: "EMPTY"> | |
| <K_ENABLE: "ENABLE"> | |
| <K_END: "END"> | |
| <K_EQUALS_PATH: "EQUALS_PATH"> | |
| <K_ESCAPE: "ESCAPE"> | |
| <K_EXCEPTION: "EXCEPTION"> | |
| <K_EXCEPTION_INIT: "EXCEPTION_INIT"> | |
| <K_EXIT: "EXIT"> | |
| <K_FALSE: "FALSE"> | |
| <K_FINAL: "FINAL"> | |
| <K_FIPSFLAG: "FIPSFLAG"> | |
| <K_FIRST: "FIRST"> | |
| <K_FLOAT: "FLOAT"> | |
| <K_FORCE: "FORCE"> | |
| <K_FULL: "FULL"> | |
| <K_FUNCTION: "FUNCTION"> | |
| <K_GLOBAL: "GLOBAL"> | |
| <K_GROUPING: "GROUPING"> | |
| <K_IGNORE: "IGNORE"> | |
| <K_IN: "IN"> | |
| <K_INCREMENT: "INCREMENT"> | |
| <K_INDEX: "INDEX"> | |
| <K_INFINITE: "INFINITE"> | |
| <K_INLINE: "INLINE"> | |
| <K_INNER: "INNER"> | |
| <K_INSTANTIABLE: "INSTANTIABLE"> | |
| <K_INT: "INT"> | |
| <K_INTEGER: "INTEGER"> | |
| <K_INTERFACE: "INTERFACE"> | |
| <K_INTERVAL: "INTERVAL"> | |
| <K_IS: "IS"> | |
| <K_ITERATE: "ITERATE"> | |
| <K_JOIN: "JOIN"> | |
| <K_KEY: "KEY"> | |
| <K_KEEP: "KEEP"> | |
| <K_LAST: "LAST"> | |
| <K_LEFT: "LEFT"> | |
| <K_LIKE2: "LIKE2"> | |
| <K_LIKE4: "LIKE4"> | |
| <K_LIKEC: "LIKEC"> | |
| <K_LOCAL: "LOCAL"> | |
| <K_LONG: "LONG"> | |
| <K_LOOP: "LOOP"> | |
| <K_MAIN: "MAIN"> | |
| <K_MEASURES: "MEASURES"> | |
| <K_MEMBER: "MEMBER"> | |
| <K_MLSLABEL: "MLSLABEL"> | |
| <K_MODEL: "MODEL"> | |
| <K_MONTH: "MONTH"> | |
| <K_NAN: "NAN"> | |
| <K_NATIONAL: "NATIONAL"> | |
| <K_NATURAL: "NATURAL"> | |
| <K_NAV: "NAV"> | |
| <K_NCHAR: "NCHAR"> | |
| <K_NCLOB: "NCLOB"> | |
| <K_NEW_NAMES: "NEW_NAMES"> | |
| <K_NO: "'NO'"> | |
| <K_NOCOMPRESS: "NOCOMPRESS"> | |
| <K_NOCOPY: "NOCOPY"> | |
| <K_NOCYCLE: "NOCYCLE"> | |
| <K_NOT: "NOT"> | |
| <K_NULL: "NULL"> | |
| <K_NULLS: "NULLS"> | |
| <K_NUMBER: "NUMBER"> | |
| <K_NUMERIC: "NUMERIC"> | |
| <K_NVARCHAR2: "NVARCHAR2"> | |
| <K_NVARCHAR: "NVARCHAR"> | |
| <K_OBJECT: "OBJECT"> | |
| <K_OF: "OF"> | |
| <K_OID: "OID"> | |
| <K_ON: "ON"> | |
| <K_ONLY: "ONLY"> | |
| <K_OPEN: "OPEN"> | |
| <K_OR: "OR"> | |
| <K_ORGANIZATION: "ORGANIZATION"> | |
| <K_OUT: "OUT"> | |
| <K_OUTER: "OUTER"> | |
| <K_OVERFLOW: "OVERFLOW"> | |
| <K_PACKAGE: "PACKAGE"> | |
| <K_PARALLEL_ENABLE: "PARALLEL_ENABLE"> | |
| <K_PARTITION: "PARTITION"> | |
| <K_PIPELINED: "PIPELINED"> | |
| <K_PLS_INTEGER: "PLS_INTEGER"> | |
| <K_POSITIVE: "POSITIVE"> | |
| <K_PRAGMA: "PRAGMA"> | |
| <K_PRECISION: "PRECISION"> | |
| <K_PRESENT: "PRESENT"> | |
| <K_PRESERVE: "PRESERVE"> | |
| <K_PRIMARY: "PRIMARY"> | |
| <K_PROCEDURE: "PROCEDURE"> | |
| <K_RAISE: "RAISE"> | |
| <K_RANGE: "RANGE"> | |
| <K_RAW: "RAW"> | |
| <K_READ: "READ"> | |
| <K_REAL: "REAL"> | |
| <K_RECORD: "RECORD"> | |
| <K_REF: "REF"> | |
| <K_REFERENCE: "REFERENCE"> | |
| <K_REGEXP_LIKE: "REGEXP_LIKE"> | |
| <K_REPLACE: "REPLACE"> | |
| <K_RESTRICT_REFERENCES: "RESTRICT_REFERENCES"> | |
| <K_RESULT_CACHE: "RESULT_CACHE"> | |
| <K_RETURN: "RETURN"> | |
| <K_RETURNING: "RETURNING"> | |
| <K_REVERSE: "REVERSE"> | |
| <K_RIGHT: "RIGHT"> | |
| <K_RNDS: "RNDS"> | |
| <K_RNPS: "RNPS"> | |
| <K_ROLLBACK: "ROLLBACK"> | |
| <K_ROLLUP: "ROLLUP"> | |
| <K_ROWID: "ROWID"> | |
| <K_ROWS: "ROWS"> | |
| <K_ROWTYPE: "%ROWTYPE"> | |
| <K_RULES: "RULES"> | |
| <K_SECOND: "SECOND"> | |
| <K_SEQUENTIAL: "SEQUENTIAL"> | |
| <K_SERIALLY_REUSABLE: "SERIALLY_REUSABLE"> | |
| <K_SESSIONTIMEZONE: "SESSIONTIMEZONE"> | |
| <K_SET: "SET"> | |
| <K_SETS: "SETS"> | |
| <K_SIBLINGS: "SIBLINGS"> | |
| <K_SIGNTYPE: "SIGNTYPE"> | |
| <K_SINGLE: "SINGLE"> | |
| <K_SIMPLE_INTEGER: "SIMPLE_INTEGER"> | |
| <K_SIMPLE_DOUBLE: "SIMPLE_DOUBLE"> | |
| <K_SIMPLE_FLOAT: "SIMPLE_FLOAT"> | |
| <K_SMALLINT: "SMALLINT"> | |
| <K_SOME: "SOME"> | |
| <K_STRING: "STRING"> | |
| <K_SUBMUlookISET: "SUBMUlookISET"> | |
| <K_SUBTYPE: "SUBTYPE"> | |
| <K_SYS_REFCURSOR: "SYS_REFCURSOR"> | |
| <K_TABLE: "TABLE"> | |
| <K_TEMPORARY: "TEMPORARY"> | |
| <K_THE: "THE"> | |
| <K_TIME: "TIME"> | |
| <K_TIMESTAMP: "TIMESTAMP"> | |
| <K_TO: "TO"> | |
| <K_TRANSACTION: "TRANSACTION"> | |
| <K_TRUE: "TRUE"> | |
| <K_TRUST: "TRUST"> | |
| <K_TYPE: "TYPE"> | |
| <K_TYPE2: "%TYPE"> | |
| <K_UNDER_PATH: "UNDER_PATH"> | |
| <K_UNTIL: "UNTIL"> | |
| <K_UPDATED: "UPDATED"> | |
| <K_UPSERT: "UPSERT"> | |
| <K_UROWID: "UROWID"> | |
| <K_USING: "USING"> | |
| <K_VARCHAR2: "VARCHAR2"> | |
| <K_VARCHAR: "VARCHAR"> | |
| <K_VARRAY: "VARRAY"> | |
| <K_VARYING: "VARYING"> | |
| <K_WITH: "WITH"> | |
| <K_WHILE: "WHILE"> | |
| <K_WNDS: "WNDS"> | |
| <K_WNPS: "WNPS"> | |
| <K_WORK: "WORK"> | |
| <K_YEAR: "YEAR"> | |
| <K_YES: "'YES'"> | |
| <K_ZONE: "ZONE"> | |
} | |
// separators and operators (prefix with O_ to avoid naming conflicts) | |
TOKEN: { | |
<O_ASSIGN: ":="> | |
| <O_ASTERISK: "*"> | |
| <O_ATSIGN: "@"> | |
| <O_CLOSEPAREN: ")"> | |
| <O_CONCAT: "||"> | |
| <O_COLON: ":"> | |
| <O_COMMA: ","> | |
| <O_DOT: "."> | |
| <O_DOUBLEDOT: ".."> | |
| <O_DOLLAR: "$"> | |
| <O_PERCENT: "%"> | |
| <O_EQUAL: "="> | |
| <O_GREATER: ">"> | |
| <O_GREATEREQUAL: ">="> | |
| <O_JOINPLUS: "(+)"> | |
| <O_LESS: "<"> | |
| <O_LESSEQUAL: "<="> | |
| <O_MINUS: "-"> | |
| <O_NOTEQUAL2: "<>"> | |
| <O_NOTEQUAL: "!="> | |
| <O_OPENPAREN: "("> | |
| <O_PLUS: "+"> | |
| <O_POUND: "#"> | |
| <O_QUESTIONMARK: "?"> | |
| <O_SEMICOLON: ";"> | |
| <O_SLASH: "/"> | |
| <O_TILDE: "~"> | |
} | |
// numeric literals | |
TOKEN : { | |
<S_NUMBER: <FLOAT> | |
| <FLOAT> ( ["e","E"] ([ "-","+"])? <FLOAT> )? | |
> | |
| <#FLOAT: <INTEGER> | |
| <INTEGER> ( "." <INTEGER> )? | |
| "." <INTEGER> | |
> | |
| <#INTEGER: ( <DIGIT> )+ > | |
| <#DIGIT: ["0" - "9"] > | |
} | |
// identifiers | |
TOKEN: | |
{ | |
<S_IDENTIFIER: (<LETTER>)+ (<DIGIT> | <LETTER> | <SPECIAL_CHARS>)* > | |
| <#LETTER: ["a"-"z", "A"-"Z"] > | |
| <#SPECIAL_CHARS: "$" | "_" | "#" | "@" > | |
| <S_BIND: ":" ( <S_NUMBER> | <S_IDENTIFIER> ("." <S_IDENTIFIER>)?) > | |
| <S_CHAR_LITERAL: "'" (~["'"])* "'" ("'" (~["'"])* "'")*> | |
| <S_QUOTED_IDENTIFIER: "\"" (~["\n","\r","\""])* "\"" > | |
} | |
// stripped-down version of PLSQL grammar: only parses package/top-level DDL specifications | |
// PLSQLPackage at 'top-level' | |
PLSQLPackageType parsePLSQLPackage(): | |
{String schema = null; | |
String packageName = null; | |
PLSQLPackageType packageType = new PLSQLPackageType(); | |
} | |
{ | |
<K_CREATE> [ <K_OR> <K_REPLACE> ] <K_PACKAGE> | |
[LOOKAHEAD(2) schema=OracleObjectName() <O_DOT> ] packageName=OracleObjectName() | |
{ | |
if (schema != null) { | |
packageType.setSchema(schema); | |
} | |
packageType.setPackageName(packageName); | |
} | |
[ <K_AUTHID> [ <K_CURRENT_USER> | <K_DEFINER> ] ] | |
[ <K_AS> | <K_IS> ] | |
( packageDeclaration(packageType) )* | |
<K_END> [ OracleObjectName() ] <O_SEMICOLON> | |
<EOF> | |
{ | |
typesRepository.setDatabaseType(packageName, packageType); | |
return packageType; | |
} | |
} | |
// procedure at 'top-level' | |
ProcedureType parseTopLevelProcedure(): | |
{ProcedureType procedureType = null; | |
String schema = null; | |
String procedureName = null;} | |
{ | |
<K_CREATE> [ <K_OR> <K_REPLACE> ] <K_PROCEDURE> | |
[LOOKAHEAD(2) schema=OracleObjectName() <O_DOT> ] procedureName=OracleObjectName() | |
{ | |
procedureType = new ProcedureType(procedureName); | |
if (schema != null) { | |
procedureType.setSchema(schema); | |
} } | |
[ <O_OPENPAREN> argumentList(procedureType) <O_CLOSEPAREN> ] [ <K_AS> | <K_IS> ] | |
skipToEnd() | |
{ | |
typesRepository.setDatabaseType(procedureName, procedureType); | |
return procedureType; | |
} | |
} | |
// function at 'top-level' | |
FunctionType parseTopLevelFunction(): | |
{FunctionType functionType = null; | |
String schema = null; | |
String functionName = null; | |
ArgumentType returnType = null;} | |
{ | |
<K_CREATE> [ <K_OR> <K_REPLACE> ] <K_FUNCTION> | |
[LOOKAHEAD(2) schema=OracleObjectName() <O_DOT> ] functionName=OracleObjectName() | |
{ | |
functionType = new FunctionType(functionName); | |
if (schema != null) { | |
functionType.setSchema(schema); | |
} } | |
[ <O_OPENPAREN> argumentList(functionType) <O_CLOSEPAREN> ] returnType=functionReturnSpec() [ <K_AS> | <K_IS> ] | |
skipToEnd() | |
{ | |
functionType.setReturnArgument(returnType); | |
typesRepository.setDatabaseType(functionName, functionType); | |
return functionType; | |
} | |
} | |
// table at 'top-level' | |
TableType parseTable(): | |
{ | |
TableType tableType = null; | |
String schema = null; | |
String tableName = null; | |
Token iot = null; | |
} | |
{ | |
<K_CREATE> [ <K_GLOBAL> <K_TEMPORARY> ] <K_TABLE> | |
[LOOKAHEAD(2) schema=OracleObjectName() <O_DOT> ] tableName=OracleObjectName() | |
{ | |
tableType = new TableType(tableName); | |
if (schema != null) { | |
tableType.setSchema(schema); | |
} } | |
<O_OPENPAREN> columnDeclarations(tableType) <O_CLOSEPAREN> | |
[ <K_ORGANIZATION> ] [ iot=<K_INDEX> ] [ <K_NOCOMPRESS> ] [ <K_OVERFLOW> ] | |
[ <K_ON> <K_COMMIT > [<K_DELETE> | <K_PRESERVE> ] <K_ROWS> ] <O_SEMICOLON> | |
<EOF> | |
{ | |
if (iot != null) { | |
tableType.setIOT(true); | |
} | |
typesRepository.setDatabaseType(tableName, tableType); | |
return tableType; | |
} | |
} | |
// type at 'top-level' | |
CompositeDatabaseType parseType(): | |
{CompositeDatabaseType databaseType = null; | |
DatabaseType enclosedType = null; | |
String schema = null; | |
String typeName = null; | |
Token vsize = null; | |
boolean varray = false; | |
boolean nestedTable = false; | |
} | |
{ | |
<K_CREATE> [ <K_OR> <K_REPLACE> ] <K_TYPE> | |
[LOOKAHEAD(2) schema=OracleObjectName() <O_DOT> ] typeName=OracleObjectName() | |
[ <K_FORCE> ] [ <K_OID> <S_CHAR_LITERAL> ] [ <K_AUTHID> [ <K_CURRENT_USER> | <K_DEFINER> ] ] | |
( <K_AS> | <K_IS> ) | |
[ <K_OBJECT> <O_OPENPAREN> | |
{ | |
databaseType = new ObjectType(typeName); | |
if (schema != null) { | |
((ObjectType)databaseType).setSchema(schema); } | |
} columnDeclarations(databaseType) <O_CLOSEPAREN> | |
| <K_VARRAY> <O_OPENPAREN> vsize=<S_NUMBER> <O_CLOSEPAREN> <K_OF> | |
{ databaseType = new VArrayType(typeName); | |
if (schema != null) { | |
((VArrayType)databaseType).setSchema(schema); | |
} | |
if (vsize != null) { | |
Long size = Long.decode(vsize.image); | |
((VArrayType)databaseType).setSize(size); | |
} | |
} enclosedType=columnTypeSpec(databaseType) | |
| <K_TABLE> <K_OF> { | |
databaseType = new ObjectTableType(typeName); | |
if (schema != null) { | |
((ObjectTableType)databaseType).setSchema(schema); | |
} } enclosedType=columnTypeSpec(databaseType) | |
] | |
[ [ <K_NOT> ] ( <K_FINAL> | <K_INSTANTIABLE> ) ] [ <O_SEMICOLON> ] | |
<EOF> | |
{ | |
if (enclosedType != null) { | |
((CompositeDatabaseType)databaseType).addCompositeType(enclosedType); } | |
typesRepository.setDatabaseType(typeName, databaseType); | |
return databaseType; | |
} | |
} | |
void columnDeclarations(CompositeDatabaseType enclosingType) #void: | |
{} | |
{ | |
columnDeclaration(enclosingType) [ <O_COMMA> columnDeclarations(enclosingType) ] | |
} | |
void columnDeclaration(CompositeDatabaseType enclosingType) #void: | |
{String s = null; | |
String pk = null; | |
boolean notNull = false; | |
DatabaseType columnType = null; | |
FieldType column = null; | |
} | |
{ | |
( LOOKAHEAD(2) s=OracleObjectName() | |
{ | |
column = new FieldType(s); | |
if (enclosingType != null) { | |
enclosingType.addCompositeType(column); | |
} } | |
columnType=columnTypeSpec(enclosingType) [ <K_NOT> <K_NULL> <K_ENABLE> {notNull = true;} ] | |
| LOOKAHEAD(2) | |
[ <K_CONSTRAINT> ] [ OracleObjectName() ] <K_PRIMARY> <K_KEY> | |
<O_OPENPAREN> pkList((TableType)enclosingType) <O_CLOSEPAREN> <K_ENABLE> | |
) | |
{ | |
if (column != null) { | |
column.setDataType(columnType); | |
if (columnType instanceof UnresolvedType) { | |
((UnresolvedType)columnType).setOwningType(column); | |
} | |
if (notNull) { | |
column.setNotNull(); | |
} | |
} | |
} | |
} | |
DatabaseType columnTypeSpec(CompositeDatabaseType enclosingType): | |
{String s = null; | |
Token t = null; | |
DatabaseType dt = null;} | |
{ | |
( | |
dt=datatype() | |
| s=columnSpec() [ <O_OPENPAREN> t=<S_NUMBER> <O_CLOSEPAREN> ] | |
) | |
{ | |
if (s != null) { | |
for (String typeName : localTypes.keySet()) { | |
if (typeName.equals(s)) { | |
dt = localTypes.get(s); | |
break; | |
} | |
} | |
if (dt == null) { | |
if (t != null) { | |
Long size = Long.decode(t.image); | |
dt = new UnresolvedSizedType(s, size); | |
} | |
else { | |
dt = new UnresolvedType(s); | |
} | |
((UnresolvedType)dt).setOwningType(enclosingType); | |
} | |
} | |
return dt; | |
} | |
} | |
void pkList(TableType tableType) #void: | |
{} | |
{ | |
pk(tableType) ( <O_COMMA> pk(tableType) )* | |
} | |
void pk(TableType tableType) #void: | |
{ | |
String s = null; | |
} | |
{ | |
s=OracleObjectName() | |
{ | |
List<FieldType> columns = tableType.getColumns(); | |
for (FieldType column : columns) { | |
if (column.getFieldName().equals(s)) { | |
column.setPk(); | |
break; | |
} | |
} } | |
} | |
void packageDeclaration(PLSQLPackageType packageType) #void: | |
{} | |
{ | |
LOOKAHEAD(2) variableDeclaration(packageType) | |
| typeOrSubTypeDeclaration(packageType) | |
| cursorDeclaration(packageType) | |
| procedureSpec(packageType) | |
| functionSpec(packageType) | |
| exceptionDeclaration(packageType) | |
| pragmaDeclaration(packageType) | |
} | |
void variableDeclaration(PLSQLPackageType packageType): | |
{Token varName = null; | |
DatabaseType varType;} | |
{ | |
varName=<S_IDENTIFIER> [ <K_CONSTANT> ] varType=typeSpec() [ <K_NOT> <K_NULL> ] | |
[ variableDefaultAssignment() ] | |
<O_SEMICOLON> | |
{ | |
FieldType variable = new FieldType(varName.image); | |
variable.setDataType(varType); | |
packageType.addLocalVariable(variable); } } | |
void variableDefaultAssignment() #void: | |
{} | |
{ | |
( <O_ASSIGN> | <K_DEFAULT> ) skipToSemiColon() | |
} | |
DatabaseType datatype(): | |
{Token t = null; | |
DatabaseType dt = null; | |
Token precision = null; | |
Long sl; | |
Long pl; | |
Token scale = null; | |
Token withTimeZone = null; | |
Token withLocalTimeZone = null; | |
} | |
{ | |
<K_BINARY_INTEGER> { return BINARY_INTEGER_TYPE;} | |
| <K_BINARY_FLOAT> { return BINARY_FLOAT_TYPE;} | |
| <K_BINARY_DOUBLE> { return BINARY_DOUBLE_TYPE;} | |
| <K_NATURAL> { return NATURAL_TYPE;} | |
| <K_POSITIVE> { return POSITIVE_TYPE;} | |
| <K_SIGNTYPE> { return SIGN_TYPE;} | |
| ( t=<K_NUMBER> | |
| t=<K_NUMERIC> | |
| t=<K_DECIMAL> | |
| t=<K_DEC> | |
) [ <O_OPENPAREN> [ precision=<O_ASTERISK > | precision=<S_NUMBER> ] ( <O_COMMA> scale=<S_NUMBER> )* <O_CLOSEPAREN> ] | |
{ | |
if (t.kind == K_NUMBER || t.kind == K_NUMERIC) { | |
if (precision != null && precision.image.equals("*")) { | |
precision = null; } | |
if (precision == null) { | |
if (scale != null && scale.image.equals("0")) { | |
dt = INTEGER_TYPE; } else { | |
dt = new NumericType(); } | |
} | |
else { | |
pl = Long.decode(precision.image); | |
if (scale == null) { | |
dt = new NumericType(pl); | |
} | |
else { | |
sl = Long.decode(scale.image); | |
dt = new NumericType(pl, sl); | |
} | |
} | |
//sometimes need to know difference between NUMERIC and NUMBER | |
if (dt != INTEGER_TYPE && t.kind == K_NUMBER) { | |
((NumericType)dt).setNumberSynonym(true); | |
} | |
} | |
else if (t.kind == K_DECIMAL || t.kind == K_DEC) { | |
if (precision != null && precision.image.equals("*")) { | |
precision = null; | |
} | |
if (precision == null) { | |
dt = new DecimalType(); | |
} | |
else { | |
pl = Long.decode(precision.image); | |
if (scale == null) { | |
dt = new DecimalType(pl); | |
} | |
else { | |
sl = Long.decode(scale.image); | |
dt = new DecimalType(pl, sl); | |
} | |
} | |
} return dt; } | |
| <K_LONG> [ t=<K_RAW> ] [ <O_OPENPAREN> precision=<S_NUMBER> <O_CLOSEPAREN> ] { | |
if (t == null) { | |
if (precision == null) { | |
dt = new LongType(); | |
} | |
else { | |
pl = Long.decode(precision.image); | |
dt = new LongType(pl); | |
} | |
} | |
else { | |
if (precision == null) { | |
dt = new LongRawType(); | |
} | |
else { | |
pl = Long.decode(precision.image); | |
dt = new LongRawType(pl); | |
} | |
} | |
return dt; } | |
| <K_RAW> [ <O_OPENPAREN> precision=<S_NUMBER> <O_CLOSEPAREN> ] { | |
if (precision == null) { | |
dt = new RawType(); | |
} | |
else { | |
pl = Long.decode(precision.image); | |
dt = new RawType(pl); | |
} | |
return dt; | |
} | |
| <K_BOOLEAN> { return BOOLEAN_TYPE;} | |
| <K_DATE> { return DATE_TYPE;} | |
| LOOKAHEAD(2) <K_INTERVAL> <K_DAY> [ <O_OPENPAREN> precision=<S_NUMBER> <O_CLOSEPAREN> ] <K_TO> <K_SECOND> [ <O_OPENPAREN> scale=<S_NUMBER> <O_CLOSEPAREN> ] | |
{ | |
if (precision == null) { | |
dt = new IntervalDayToSecond(); | |
} | |
else { | |
pl = Long.decode(precision.image); | |
if (scale == null) { | |
dt = new IntervalDayToSecond(pl); | |
} | |
else { | |
sl = Long.decode(scale.image); | |
dt = new IntervalDayToSecond(pl, sl); | |
} | |
} | |
return dt; } | |
| <K_INTERVAL> <K_YEAR> [ <O_OPENPAREN> <S_NUMBER> <O_CLOSEPAREN> ] <K_TO> <K_MONTH> { | |
if (precision == null) { | |
dt = new IntervalYearToMonth(); | |
} | |
else { | |
pl = Long.decode(precision.image); | |
dt = new IntervalYearToMonth(pl); | |
} | |
return dt; } | |
| <K_TIME> { return TIME_TYPE;} | |
| <K_TIMESTAMP> [ <O_OPENPAREN> precision=<S_NUMBER> <O_CLOSEPAREN> ] | |
[ <K_WITH> [ withLocalTimeZone=<K_LOCAL> ] withTimeZone=<K_TIME> <K_ZONE> ] | |
{ | |
if (precision == null) { | |
dt = new TimeStampType(); | |
} | |
else { | |
pl = Long.decode(precision.image); | |
dt = new TimeStampType(pl); | |
} | |
if (withLocalTimeZone != null) { | |
((TimeStampType)dt).setWithLocalTimeZone(); } | |
else if (withTimeZone != null) { | |
((TimeStampType)dt).setWithTimeZone(); } | |
return dt; } | |
| <K_INTEGER> { return INTEGER_TYPE;} | |
| <K_INT> { return INTEGER_TYPE;} | |
| <K_SMALLINT> { return SMALLINT_TYPE;} | |
| <K_FLOAT> [ <O_OPENPAREN> precision=<S_NUMBER> <O_CLOSEPAREN> ] | |
{ | |
if (precision == null) { | |
return new FloatType(); | |
} | |
else { | |
pl = Long.decode(precision.image); | |
FloatType ft = new FloatType(pl); | |
return ft; } | |
} | |
| <K_REAL> { return new RealType();} | |
| <K_MLSLABEL> { return MLSLABEL_TYPE;} | |
| <K_PLS_INTEGER> { return PLS_INTEGER_TYPE;} | |
| <K_SIMPLE_INTEGER> { return SIMPLE_INTEGER_TYPE;} | |
| <K_SIMPLE_FLOAT> { return SIMPLE_FLOAT_TYPE;} | |
| <K_SIMPLE_DOUBLE> { return SIMPLE_DOUBLE_TYPE;} | |
| <K_SYS_REFCURSOR> { return SYS_REFCURSOR_TYPE;} | |
| <K_BLOB > { return new BlobType();} | |
| <K_NCLOB> { return new NClobType();} | |
| <K_BFILE> { return BFILE_TYPE;} | |
| <K_ROWID> { return ROWID_TYPE;} | |
| <K_UROWID> [ <O_OPENPAREN> precision=<S_NUMBER> <O_CLOSEPAREN> ] | |
{ | |
if (precision == null) { | |
return new URowIdType(); | |
} | |
else { | |
pl = Long.decode(precision.image); | |
return new URowIdType(pl); | |
} } | |
| <K_DOUBLE> <K_PRECISION> { return new DoubleType();} | |
| <K_CHAR> [ t=<K_VARYING> ] [ <O_OPENPAREN> precision=<S_NUMBER> [ <K_BYTE> | <K_CHAR> ] <O_CLOSEPAREN> ] | |
[ LOOKAHEAD(2) <K_CHARACTER> <K_SET> [ LOOKAHEAD(2) <S_IDENTIFIER> | columnSpec() <K_CHARSET> ] ] { | |
if (t == null) { | |
if (precision == null) { | |
return new CharType(); | |
} | |
else { | |
pl = Long.decode(precision.image); | |
return new CharType(pl); } | |
} | |
else { | |
// ANSI syntax for VARCHAR2 | |
if (precision == null) { | |
return new VarChar2Type(); | |
} | |
else { | |
pl = Long.decode(precision.image); | |
return new VarChar2Type(pl); | |
} } } | |
| <K_VARCHAR> [ <K_VARYING> ] [ <O_OPENPAREN> precision=<S_NUMBER> [ <K_BYTE> | <K_CHAR> ] <O_CLOSEPAREN> ] | |
[ LOOKAHEAD(2) <K_CHARACTER> <K_SET> [ LOOKAHEAD(2) <S_IDENTIFIER> | columnSpec() <K_CHARSET> ] ] | |
{ | |
if (precision == null) { | |
return new VarCharType(); | |
} | |
else { | |
pl = Long.decode(precision.image); | |
return new VarCharType(pl); | |
} | |
} | |
| <K_VARCHAR2> [ <K_VARYING> ] [ <O_OPENPAREN> precision=<S_NUMBER> [ <K_BYTE> | <K_CHAR> ] <O_CLOSEPAREN> ] | |
[ LOOKAHEAD(2) <K_CHARACTER> <K_SET> [ LOOKAHEAD(2) <S_IDENTIFIER> | columnSpec() <K_CHARSET> ] ] | |
{ | |
if (precision == null) { | |
return new VarChar2Type(); | |
} | |
else { | |
pl = Long.decode(precision.image); | |
return new VarChar2Type(pl); } } | |
| <K_CHARACTER> [ t=<K_VARYING> ] [ <O_OPENPAREN> precision=<S_NUMBER> <O_CLOSEPAREN> ] | |
{ | |
if (t == null) { | |
if (precision == null) { | |
return new CharType(); | |
} | |
else { | |
pl = Long.decode(precision.image); | |
return new CharType(pl); | |
} | |
} | |
else { | |
// ANSI syntax for VARCHAR | |
if (precision == null) { | |
return new VarCharType(); | |
} | |
else { | |
pl = Long.decode(precision.image); | |
return new VarCharType(pl); | |
} | |
} | |
} | |
| <K_NCHAR> [ t=<K_VARYING> ] [ <O_OPENPAREN> precision=<S_NUMBER> <O_CLOSEPAREN> ] | |
{ | |
if (t == null) { | |
if (precision == null) { | |
return new NCharType(); | |
} | |
else { | |
pl = Long.decode(precision.image); | |
return new NCharType(pl); | |
} | |
} | |
else { | |
// ANSI syntax for NVARCHAR2 | |
if (precision == null) { | |
return new NVarChar2Type(); | |
} | |
else { | |
pl = Long.decode(precision.image); | |
return new NVarChar2Type(pl); | |
} | |
} | |
} | |
| <K_NVARCHAR> [ <O_OPENPAREN> precision=<S_NUMBER> <O_CLOSEPAREN> ] { | |
if (precision == null) { | |
return new NVarChar2Type(); | |
} | |
else { | |
pl = Long.decode(precision.image); | |
return new NVarChar2Type(pl); | |
} } | |
| <K_NVARCHAR2> [ <O_OPENPAREN> precision=<S_NUMBER> <O_CLOSEPAREN> ] | |
{ | |
if (precision == null) { | |
return new NVarChar2Type(); | |
} | |
else { | |
pl = Long.decode(precision.image); | |
return new NVarChar2Type(pl); | |
} | |
} | |
| <K_NATIONAL> ( <K_CHARACTER> | <K_CHAR> ) [ t=<K_VARYING> ] [ <O_OPENPAREN> precision=<S_NUMBER> <O_CLOSEPAREN> ] | |
{ | |
if (t == null) { | |
if (precision == null) { | |
return new NCharType(); | |
} | |
else { | |
pl = Long.decode(precision.image); | |
return new NCharType(pl); | |
} | |
} | |
else { | |
// ANSI syntax for NVARCHAR2 | |
if (precision == null) { | |
return new NVarChar2Type(); | |
} | |
else { | |
pl = Long.decode(precision.image); | |
return new NVarChar2Type(pl); | |
} | |
} | |
} | |
| <K_CLOB> [ LOOKAHEAD(2) <K_CHARACTER> <K_SET> [ LOOKAHEAD(2) <S_IDENTIFIER> | columnSpec() <K_CHARSET> ] ] { return new ClobType();} | |
} | |
DatabaseType typeSpec(): | |
{DatabaseType dataType = null; | |
String s = null;} | |
{ | |
( | |
dataType=datatype() | |
| | |
s=columnSpec() | |
[ | |
( <O_OPENPAREN> <S_NUMBER> <O_CLOSEPAREN> ) | | |
<K_TYPE2> {s += tokenImage[K_TYPE2].substring(1, tokenImage[K_TYPE2].length() - 1);} | | |
<K_ROWTYPE> {s += tokenImage[K_ROWTYPE].substring(1, tokenImage[K_ROWTYPE].length() - 1);} | |
] | |
) | |
{ | |
if (dataType == null && localTypes != null) { | |
for (String typeName : localTypes.keySet()) { | |
if (typeName.equals(s)) { | |
dataType = localTypes.get(s); | |
break; | |
} | |
} | |
} | |
if (dataType == null) { | |
dataType = new UnresolvedType(s); | |
} | |
return dataType; } | |
} | |
String columnSpec() #void: | |
{String s1 = null; | |
String s2 = null; | |
String s3 = null;} | |
{ | |
s1=OracleObjectName() [ <O_DOT> s2=OracleObjectName() [ <O_DOT> s3=OracleObjectName() ] ] | |
{ | |
StringBuilder sb = new StringBuilder(s1); | |
if (s2 != null) { | |
sb.append('.'); | |
sb.append(s2); | |
if (s3 != null) { | |
sb.append('.'); | |
sb.append(s3); | |
} | |
} | |
return sb.toString(); | |
} | |
} | |
String tableSpec() #void: | |
{} | |
{ | |
OracleObjectName() [ <O_DOT> OracleObjectName() [ <O_ATSIGN> <S_IDENTIFIER> ] ] | |
{return token.image;} | |
} | |
String typeName() #void: | |
{} | |
{ | |
OracleObjectName() [ <O_DOT> OracleObjectName() ] | |
{return token.image;} | |
} | |
void typeOrSubTypeDeclaration(PLSQLPackageType packageType) #void: | |
{String s = null;} | |
{ | |
typeDeclaration(packageType) | |
| subtypeDeclaration(packageType) | |
} | |
void typeDeclaration(PLSQLPackageType packageType) #void: | |
{String s = null;} | |
{ | |
<K_TYPE> s=typeName() <K_IS> aTypeDeclaration(packageType, s) <O_SEMICOLON> | |
} | |
void aTypeDeclaration(PLSQLPackageType packageType, String typeName) #void: | |
{} | |
{ | |
recordDeclaration(packageType, typeName) | |
| plsqlTableDeclaration(packageType, typeName) | |
| varrayDeclaration(packageType) | |
| refCursorDeclaration(packageType, typeName) | |
} | |
void recordDeclaration(PLSQLPackageType packageType, String typeName) #void: | |
{ | |
PLSQLRecordType plsqlRecordType = new PLSQLRecordType(typeName); | |
plsqlRecordType.setParentType(packageType); | |
} | |
{ | |
<K_RECORD> <O_OPENPAREN> | |
fieldDeclarations(plsqlRecordType) | |
<O_CLOSEPAREN> | |
{ packageType.addType(plsqlRecordType); | |
localTypes.put(typeName, plsqlRecordType); | |
} | |
} | |
void fieldDeclarations(PLSQLRecordType plsqlRecordType) #void: | |
{} | |
{ | |
fieldDeclaration(plsqlRecordType) [ <O_COMMA> fieldDeclarations(plsqlRecordType) ] | |
} | |
void fieldDeclaration(PLSQLRecordType plsqlRecordType): | |
{ | |
String s = null; | |
DatabaseType dataType = null; | |
FieldType fieldType = null; | |
} | |
{ | |
s=typeName() dataType=typeSpec() [ <K_NOT> <K_NULL> ] [ fieldDefaultAssignment() ] | |
{ | |
fieldType = new FieldType(s); | |
fieldType.setDataType(dataType); | |
plsqlRecordType.addCompositeType(fieldType); | |
if (dataType instanceof UnresolvedType) { | |
((UnresolvedType)dataType).setOwningType(plsqlRecordType); | |
} } | |
} | |
void fieldDefaultAssignment() #void: | |
{} | |
{ | |
( <O_ASSIGN> | <K_DEFAULT> ) skipToNextArg() | |
} | |
void subtypeDeclaration(PLSQLPackageType packageType) #void: | |
{String subtypeName; | |
DatabaseType subtype; | |
Token notNull = null; | |
Token rangeStart = null; | |
Token rangeEnd = null;} | |
{ | |
<K_SUBTYPE> subtypeName=OracleObjectName() <K_IS> subtype=typeSpec() | |
[ <K_RANGE> rangeStart=<S_NUMBER> <O_DOUBLEDOT> rangeEnd=<S_NUMBER> ] | |
[ <K_NOT> notNull=<K_NULL> ] <O_SEMICOLON> | |
{ | |
PLSQLSubType newPLSQLSubType = new PLSQLSubType(subtypeName); | |
newPLSQLSubType.addCompositeType(subtype); | |
if (subtype instanceof UnresolvedType) { | |
((UnresolvedType)subtype).setOwningType(newPLSQLSubType); } | |
packageType.addType(newPLSQLSubType); | |
if (notNull != null) { | |
newPLSQLSubType.setNotNull(true); } | |
if (rangeStart != null) { | |
long rStart = Long.decode(rangeStart.image).longValue(); | |
long rEnd = Long.decode(rangeEnd.image).longValue(); | |
newPLSQLSubType.setHasRange(true); | |
newPLSQLSubType.setRangeStart(rStart); | |
newPLSQLSubType.setRangeEnd(rEnd); } | |
localTypes.put(subtypeName, newPLSQLSubType); | |
} | |
} | |
void plsqlTableDeclaration(PLSQLPackageType packageType, String typeName) #void: | |
{ | |
PLSQLCollectionType plsqlTable = new PLSQLCollectionType(typeName); | |
plsqlTable.setParentType(packageType); | |
DatabaseType nestedType; | |
} | |
{ | |
<K_TABLE> <K_OF> nestedType = typeSpec() [ <K_NOT> <K_NULL> ] | |
[ <K_INDEX> <K_BY> plsqlTableIndexByDeclaration(plsqlTable) ] | |
{ | |
if (nestedType instanceof UnresolvedType) { | |
((UnresolvedType)nestedType).setOwningType(plsqlTable); } | |
plsqlTable.addCompositeType(nestedType); | |
packageType.addType(plsqlTable); | |
// TODO - TBD typesRepository.setDatabaseType(typeName, plsqlTable); | |
localTypes.put(typeName, plsqlTable); | |
} | |
} | |
void plsqlTableIndexByDeclaration(PLSQLCollectionType plsqlTable) #void: | |
{ | |
DatabaseType indexType = null; | |
Token precision = null; | |
Token otherIndexByType = null; | |
} | |
{ | |
( <K_PLS_INTEGER> {indexType = PLS_INTEGER_TYPE; } | |
| <K_BINARY_INTEGER> {indexType = BINARY_INTEGER_TYPE; } | |
| <K_VARCHAR2> <O_OPENPAREN> precision=<S_NUMBER> <O_CLOSEPAREN> | |
{ | |
if (precision == null) { | |
indexType = new VarChar2Type(); | |
} | |
else { | |
Long pl = Long.decode(precision.image); | |
indexType = new VarChar2Type(pl); | |
} | |
} | |
| otherIndexByType=<K_STRING> <O_OPENPAREN> <S_NUMBER> <O_CLOSEPAREN> | |
{ | |
String indexTypename = otherIndexByType.image; | |
for (String typeName : localTypes.keySet()) { | |
if (typeName.equals(indexTypename)) { | |
indexType = localTypes.get(indexTypename); | |
break; | |
} | |
} | |
//what else can INDEX BY be? Unresolved for now ... | |
if (indexType == null) { | |
indexType = new UnresolvedType(indexTypename); | |
((UnresolvedType)indexType).setOwningType(plsqlTable); | |
} | |
} | |
) | |
{ plsqlTable.setIndexed(true); | |
plsqlTable.setIndexType(indexType); | |
} | |
} | |
void varrayDeclaration(PLSQLPackageType packageType) #void: | |
{} | |
{ | |
( <K_VARRAY> | <K_VARYING> <K_ARRAY> ) <O_OPENPAREN> <S_NUMBER> <O_CLOSEPAREN> | |
<K_OF> datatype() [ <K_NOT> <K_NULL> ] | |
} | |
void refCursorDeclaration(PLSQLPackageType packageType, String cursorTypeName) #void: | |
{PLSQLCursorType cursorType = null;} | |
{ | |
<K_REF> <K_CURSOR> | |
{ | |
cursorType = new PLSQLCursorType(cursorTypeName); | |
packageType.addCursor(cursorType); | |
localTypes.put(cursorTypeName, cursorType); | |
} | |
[ refCursorTypeSpec(cursorType) ] | |
} | |
void refCursorTypeSpec(PLSQLCursorType cursorType) #void: | |
{String s = null;} | |
{ | |
<K_RETURN> [LOOKAHEAD(3) s=columnSpec() [ <K_TYPE2> | |
{ | |
s += tokenImage[K_TYPE2].substring(1, tokenImage[K_TYPE2].length() - 1); | |
} | |
] | |
| LOOKAHEAD(3) s=tableSpec() [ <K_ROWTYPE> | |
{ | |
s += tokenImage[K_ROWTYPE].substring(1, tokenImage[K_ROWTYPE].length() - 1); | |
} | |
] | |
] | |
{ | |
DatabaseType localType = localTypes.get(s); | |
if (localType == null) { cursorType.setDataType(new UnresolvedType(s)); | |
} | |
else { | |
cursorType.setDataType(localType); } } | |
} | |
void cursorDeclaration(PLSQLPackageType packageType) #void: | |
{Token t = null;} | |
{ | |
<K_CURSOR> t=<S_IDENTIFIER> | |
<O_SEMICOLON> | |
} | |
// Procedure Specification | |
void procedureSpec(PLSQLPackageType packageType) #void: | |
{Token t = null; | |
ProcedureType procedureType = null; | |
} | |
{ | |
<K_PROCEDURE> t=<S_IDENTIFIER> { | |
procedureType = new ProcedureType(t.image); | |
procedureType.setCatalogName(packageType.getPackageName()); | |
procedureType.setSchema(packageType.getSchema()); } | |
[ <O_OPENPAREN> argumentList(procedureType) <O_CLOSEPAREN> ] | |
<O_SEMICOLON> | |
{ packageType.addProcedure(procedureType); | |
} | |
} | |
void argumentList(ProcedureType procedureType) #void: | |
{} | |
{ | |
argument(procedureType) ( <O_COMMA> argument(procedureType) )* | |
} | |
// Function Specification | |
void functionSpec(PLSQLPackageType packageType) #void: | |
{Token t = null; | |
FunctionType functionType = null; | |
ArgumentType returnDataType = null; | |
} | |
{ | |
<K_FUNCTION> t=<S_IDENTIFIER> | |
{ | |
functionType = new FunctionType(t.image); | |
functionType.setCatalogName(packageType.getPackageName()); | |
functionType.setSchema(packageType.getSchema()); | |
} | |
[ <O_OPENPAREN> argumentList(functionType) <O_CLOSEPAREN> ] | |
returnDataType = functionReturnSpec() | |
[ <K_DETERMINISTIC> | <K_PIPELINED> | <K_PARALLEL_ENABLE> | <K_RESULT_CACHE> ] | |
<O_SEMICOLON> | |
{ | |
functionType.setReturnArgument(returnDataType); | |
packageType.addProcedure(functionType); | |
} | |
} | |
ArgumentType functionReturnSpec(): | |
{DatabaseType dataType = null;} { (<K_RETURN> dataType=typeSpec()) | |
{ | |
ArgumentType returnType = new ArgumentType(null); | |
returnType.setDirection(ArgumentTypeDirection.RETURN); | |
returnType.setDataType(dataType); | |
if (dataType instanceof UnresolvedType) { | |
((UnresolvedType)dataType).setOwningType(returnType); } | |
return returnType; | |
} | |
} | |
void argument(ProcedureType procedureType) #void: | |
{Token t = null; | |
ArgumentType argumentType = null; | |
DatabaseType argumentDataType = null; | |
ArgumentTypeDirection argDirection = ArgumentTypeDirection.IN; // by default, arguments are IN | |
String direction = null; | |
boolean defaultAssignment = false; | |
} | |
{ | |
t=<S_IDENTIFIER> [(direction=direction())] | |
[ <K_NOCOPY> ] argumentDataType=typeSpec() [ defaultAssignment=argumentDefaultAssignment() ] | |
{ | |
argumentType = new ArgumentType(t.image); | |
argumentType.setDataType(argumentDataType); | |
if (argumentDataType instanceof UnresolvedType) { | |
((UnresolvedType)argumentDataType).setOwningType(argumentType); | |
} | |
if (direction != null) { | |
if ("OUT".equals(direction)) { | |
argDirection = ArgumentTypeDirection.OUT; | |
} | |
else if ("IN OUT".equals(direction)) { | |
argDirection = ArgumentTypeDirection.INOUT; } | |
argumentType.setDirection(argDirection); } if (defaultAssignment) { | |
argumentType.setOptional(); } | |
procedureType.addCompositeType(argumentType); | |
} | |
} | |
String direction() #void: | |
{} | |
{ | |
LOOKAHEAD(2) <K_IN> <K_OUT> { return "IN OUT"; } | |
| <K_IN> { return "IN"; } | |
| <K_OUT> { return "OUT"; } | |
} | |
boolean argumentDefaultAssignment(): | |
{} | |
{ | |
( <O_ASSIGN> | <K_DEFAULT> ) skipToNextArg() | |
{ | |
return true; | |
} | |
} | |
void exceptionDeclaration(PLSQLPackageType packageType) #void: | |
{} | |
{ | |
<S_IDENTIFIER> <K_EXCEPTION> <O_SEMICOLON> | |
} | |
void pragmaDeclaration(PLSQLPackageType packageType) #void: | |
{} | |
{ <K_PRAGMA> | |
[ <K_AUTONOMOUS_TRANSACTION> | |
| <K_EXCEPTION_INIT> <O_OPENPAREN> <S_IDENTIFIER> <O_COMMA> <S_NUMBER> <O_CLOSEPAREN> | |
| <K_SERIALLY_REUSABLE> | |
| <K_INLINE> <O_OPENPAREN> <S_IDENTIFIER> <O_COMMA> [ <K_YES> | <K_NO> ] <O_CLOSEPAREN> | |
| <K_RESTRICT_REFERENCES> <O_OPENPAREN> [ <S_IDENTIFIER> | <K_DEFAULT> ] | |
( <O_COMMA> [ <K_RNDS> | <K_WNDS> | <K_RNPS> | <K_WNPS> | <K_TRUST>] )+ <O_CLOSEPAREN> | |
] | |
<O_SEMICOLON> | |
} | |
String OracleObjectName() #void: | |
{} | |
{ | |
<S_IDENTIFIER> | |
{return token.image;} | |
| <S_QUOTED_IDENTIFIER> | |
{ | |
String s = token.image; | |
return s.substring(1, s.length() - 1); // strip-off quotes | |
} | |
} | |
void skipToSemiColon() #void: | |
{} | |
{ | |
{ | |
Token t = getNextToken(); | |
while (t.kind != O_SEMICOLON) { | |
t = getNextToken(); | |
} | |
token_source.input_stream.backup(1); | |
} | |
} | |
void skipToNextArg() #void: | |
{} | |
{ | |
{ | |
Token t = getNextToken(); | |
while (t.kind != O_COMMA && t.kind != O_CLOSEPAREN) { | |
t = getNextToken(); | |
} | |
token_source.input_stream.backup(1); | |
} | |
} | |
void skipToEnd() #void: | |
{} | |
{ | |
{ | |
/** skip through all the tokens. */ | |
Token t = getNextToken(); | |
while (t.kind != EOF) { | |
t = getNextToken(); | |
} | |
} | |
} |