All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.teiid.modeshape.sequencer.ddl.AlterOptionsParser Maven / Gradle / Ivy

/*
 * JBoss, Home of Professional Open Source.
 * See the COPYRIGHT.txt file distributed with this work for information
 * regarding copyright ownership.  Some portions may be licensed
 * to Red Hat, Inc. under one or more contributor license agreements.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
 * 02110-1301 USA.
 */
package org.teiid.modeshape.sequencer.ddl;

import java.util.ArrayList;
import java.util.List;
import org.modeshape.common.text.ParsingException;
import org.modeshape.common.util.StringUtil;
import org.teiid.modeshape.sequencer.ddl.TeiidDdlConstants.DdlStatement;
import org.teiid.modeshape.sequencer.ddl.TeiidDdlConstants.SchemaElementType;
import org.teiid.modeshape.sequencer.ddl.TeiidDdlConstants.TeiidReservedWord;
import org.teiid.modeshape.sequencer.ddl.node.AstNode;

/**
 * A parser for the Teiid  DDL statement.
 * 

* * ALTER ( VIRTUAL | FOREIGN )? ( TABLE | VIEW | PROCEDURE ) ( | ) * */ final class AlterOptionsParser extends StatementParser { AlterOptionsParser( final TeiidDdlParser teiidDdlParser ) { super(teiidDdlParser); } /** * {@inheritDoc} * * @see org.teiid.modeshape.sequencer.ddl.StatementParser#matches(org.teiid.modeshape.sequencer.ddl.DdlTokenStream) */ @Override boolean matches( final DdlTokenStream tokens ) { return tokens.matches(DdlStatement.ALTER_VIRTUAL_PROCEDURE.tokens()) || tokens.matches(DdlStatement.ALTER_VIRTUAL_TABLE.tokens()) || tokens.matches(DdlStatement.ALTER_VIRTUAL_VIEW.tokens()) || tokens.matches(DdlStatement.ALTER_FOREIGN_PROCEDURE.tokens()) || tokens.matches(DdlStatement.ALTER_FOREIGN_TABLE.tokens()) || tokens.matches(DdlStatement.ALTER_FOREIGN_VIEW.tokens()) || tokens.matches(DdlStatement.ALTER_PROCEDURE.tokens()) || tokens.matches(DdlStatement.ALTER_TABLE.tokens()) || tokens.matches(DdlStatement.ALTER_VIEW.tokens()); } /** * {@inheritDoc} * * @see org.teiid.modeshape.sequencer.ddl.StatementParser#parse(org.teiid.modeshape.sequencer.ddl.DdlTokenStream, * org.teiid.modeshape.sequencer.ddl.node.AstNode) */ @Override AstNode parse( final DdlTokenStream tokens, final AstNode parentNode ) throws ParsingException { // ALTER TABLE // ALTER TABLE // ALTER VIEW // ALTER VIEW // ALTER PROCEDURE // ALTER PROCEDURE // ALTER VIRTUAL TABLE // ALTER VIRTUAL TABLE // ALTER VIRTUAL VIEW // ALTER VIRTUAL VIEW // ALTER VIRTUAL PROCEDURE // ALTER VIRTUAL PROCEDURE // ALTER FOREIGN TABLE // ALTER FOREIGN TABLE // ALTER FOREIGN VIEW // ALTER FOREIGN VIEW // ALTER FOREIGN PROCEDURE // ALTER FOREIGN PROCEDURE String nodeType = null; SchemaElementType schemaElementType = null; String refNodeType = null; if (tokens.canConsume(DdlStatement.ALTER_TABLE.tokens())) { nodeType = TeiidDdlLexicon.AlterOptions.TABLE_STATEMENT; schemaElementType = SchemaElementType.FOREIGN; refNodeType = TeiidDdlLexicon.CreateTable.TABLE_STATEMENT; } else if (tokens.canConsume(DdlStatement.ALTER_VIEW.tokens())) { nodeType = TeiidDdlLexicon.AlterOptions.VIEW_STATEMENT; schemaElementType = SchemaElementType.FOREIGN; refNodeType = TeiidDdlLexicon.CreateTable.VIEW_STATEMENT; } else if (tokens.canConsume(DdlStatement.ALTER_PROCEDURE.tokens())) { nodeType = TeiidDdlLexicon.AlterOptions.PROCEDURE_STATEMENT; schemaElementType = SchemaElementType.FOREIGN; refNodeType = TeiidDdlLexicon.CreateProcedure.PROCEDURE_STATEMENT; } else if (tokens.canConsume(DdlStatement.ALTER_VIRTUAL_TABLE.tokens())) { nodeType = TeiidDdlLexicon.AlterOptions.TABLE_STATEMENT; schemaElementType = SchemaElementType.VIRTUAL; refNodeType = TeiidDdlLexicon.CreateTable.TABLE_STATEMENT; } else if (tokens.canConsume(DdlStatement.ALTER_VIRTUAL_VIEW.tokens())) { nodeType = TeiidDdlLexicon.AlterOptions.VIEW_STATEMENT; schemaElementType = SchemaElementType.VIRTUAL; refNodeType = TeiidDdlLexicon.CreateTable.VIEW_STATEMENT; } else if (tokens.canConsume(DdlStatement.ALTER_VIRTUAL_PROCEDURE.tokens())) { nodeType = TeiidDdlLexicon.AlterOptions.PROCEDURE_STATEMENT; schemaElementType = SchemaElementType.VIRTUAL; refNodeType = TeiidDdlLexicon.CreateProcedure.PROCEDURE_STATEMENT; } else if (tokens.canConsume(DdlStatement.ALTER_FOREIGN_TABLE.tokens())) { nodeType = TeiidDdlLexicon.AlterOptions.TABLE_STATEMENT; schemaElementType = SchemaElementType.FOREIGN; refNodeType = TeiidDdlLexicon.CreateTable.TABLE_STATEMENT; } else if (tokens.canConsume(DdlStatement.ALTER_FOREIGN_VIEW.tokens())) { nodeType = TeiidDdlLexicon.AlterOptions.VIEW_STATEMENT; schemaElementType = SchemaElementType.FOREIGN; refNodeType = TeiidDdlLexicon.CreateTable.VIEW_STATEMENT; } else if (tokens.canConsume(DdlStatement.ALTER_FOREIGN_PROCEDURE.tokens())) { nodeType = TeiidDdlLexicon.AlterOptions.PROCEDURE_STATEMENT; schemaElementType = SchemaElementType.FOREIGN; refNodeType = TeiidDdlLexicon.CreateProcedure.PROCEDURE_STATEMENT; } else { throw new TeiidDdlParsingException(tokens, "Unparsable alter options statement"); } assert (nodeType != null) : "Create alter options node type is null"; assert (schemaElementType != null) : "Create alter options schema element type is null"; assert (refNodeType != null) : "Create alter options reference node type is null"; // parse table reference final String tableRefName = parseIdentifier(tokens); final AstNode alterOptionsNode = getNodeFactory().node(tableRefName, parentNode, nodeType); alterOptionsNode.setProperty(TeiidDdlLexicon.SchemaElement.TYPE, schemaElementType.toDdl()); // find referenced table node final AstNode tableRefNode = getNode(parentNode, tableRefName, refNodeType); // can't find referenced table if (tableRefNode == null) { // // Causes a constraint violation exception as REFERENCE is mandatory // throw new TeiidDdlParsingException(tokens, "Alter options statement table reference '" + tableRefName + "' node not found"); } alterOptionsNode.setProperty(TeiidDdlLexicon.AlterOptions.REFERENCE, tableRefNode); // must have either a or a if (!parseAlterOptionsList(tokens, alterOptionsNode) && !parseAlterColumnOptions(tokens, alterOptionsNode)) { throw new TeiidDdlParsingException(tokens, "Unparsable alter options statement"); } return alterOptionsNode; } /** * * ALTER ( COLUMN | PARAMETER )? * * * @param tokens the tokens being processed (cannot be null) * @param alterOptionsNode the alter options node of the alter column options (cannot be null) * @return true if an alter column options clause was successfully parsed * @throws ParsingException if there is a problem parsing the alter options statement */ boolean parseAlterColumnOptions( final DdlTokenStream tokens, final AstNode alterOptionsNode ) throws ParsingException { // ALTER COLUMN // ALTER PARAMATER // ALTER if (tokens.canConsume(TeiidReservedWord.ALTER.toDdl())) { String nodeType = null; if (tokens.canConsume(TeiidReservedWord.COLUMN.toDdl())) { nodeType = TeiidDdlLexicon.AlterOptions.COLUMN; } else if (tokens.canConsume(TeiidReservedWord.PARAMETER.toDdl())) { nodeType = TeiidDdlLexicon.AlterOptions.PARAMETER; } else { nodeType = TeiidDdlLexicon.AlterOptions.COLUMN; } assert (nodeType != null) : "Alter column options node type is null"; final String refName = parseIdentifier(tokens); final AstNode columnOptionsNode = getNodeFactory().node(refName, alterOptionsNode, nodeType); // find referenced column/parameter final AstNode refTableNode = (AstNode)alterOptionsNode.getProperty(TeiidDdlLexicon.AlterOptions.REFERENCE); if (refTableNode == null) { this.logger.debug("Table/procedure/view node not found for alter column '{0}'", refName); } else { String refPropType = null; if (refTableNode.hasMixin(TeiidDdlLexicon.CreateProcedure.PROCEDURE_STATEMENT)) { refPropType = TeiidDdlLexicon.CreateProcedure.PARAMETER; } else { refPropType = TeiidDdlLexicon.CreateTable.TABLE_ELEMENT; } final AstNode refNode = getNode(refTableNode, refName, refPropType); // can't find referenced column node if (refNode == null) { this.logger.debug("Alter column options reference column node not found: {0}", refName); } columnOptionsNode.setProperty(TeiidDdlLexicon.AlterOptions.REFERENCE, refNode); } if (parseAlterOptionsList(tokens, columnOptionsNode)) { return true; // well formed } throw new TeiidDdlParsingException(tokens, "Unparsable alter column options clause"); } return false; } /** * * OPTIONS ( | ) ( ( | ) )* * * == ( ADD | SET ) * * @param tokens the tokens being processed (cannot be null) * @param parentNode the parent node of the alter options list (cannot be null) * @return true if an alter options list clause was successfully parsed; false if not an alter * options list clause * @throws ParsingException if there is a problem parsing the alter options list clause */ @SuppressWarnings( "unchecked" ) boolean parseAlterOptionsList( final DdlTokenStream tokens, final AstNode parentNode ) throws ParsingException { // OPTIONS () // OPTIONS () // OPTIONS (, , , ) if (tokens.matches(TeiidReservedWord.OPTIONS.toDdl())) { // must have opening paren if (!tokens.canConsume(TeiidReservedWord.OPTIONS.toDdl(), L_PAREN)) { throw new TeiidDdlParsingException(tokens, "Unparsable alter options list (left paren not found)"); } if (tokens.matches(TeiidReservedWord.ADD.toDdl()) || tokens.matches(TeiidReservedWord.SET.toDdl()) || tokens.matches(TeiidReservedWord.DROP.toDdl())) { // create options list node AstNode optionsListNode = null; if (parentNode.hasMixin(TeiidDdlLexicon.AlterOptions.COLUMN) || parentNode.hasMixin(TeiidDdlLexicon.AlterOptions.PARAMETER)) { optionsListNode = parentNode; } else { optionsListNode = getNodeFactory().node(TeiidDdlLexicon.AlterOptions.ALTERS, parentNode, TeiidDdlLexicon.AlterOptions.OPTIONS_LIST); } // will have one or more add, set, or drop clauses separated by comma boolean keepParsing = tokens.hasNext(); boolean foundOption = false; boolean foundComma = false; while (keepParsing) { if (tokens.canConsume(TeiidReservedWord.ADD.toDdl()) || tokens.canConsume(TeiidReservedWord.SET.toDdl())) { final String option = parseIdentifier(tokens); final String value = parseValue(tokens); // only add if there is a value if (!StringUtil.isBlank(value)) { final AstNode optionsNode = getNodeFactory().node(option, optionsListNode, StandardDdlLexicon.TYPE_STATEMENT_OPTION); optionsNode.setProperty(StandardDdlLexicon.VALUE, value); } foundOption = true; foundComma = false; } else if (tokens.canConsume(TeiidReservedWord.DROP.toDdl())) { final String option = parseIdentifier(tokens); List values = (List)optionsListNode.getProperty(TeiidDdlLexicon.AlterOptions.DROPPED); if (values == null) { values = new ArrayList(); } values.add(option); optionsListNode.setProperty(TeiidDdlLexicon.AlterOptions.DROPPED, values); foundOption = true; foundComma = false; } else if (tokens.canConsume(COMMA)) { // found comma before option if (!foundOption) { throw new TeiidDdlParsingException(tokens, "Unparsable alter options list (misplaced comma found)"); } // 2 consecutive commas if (foundComma) { throw new TeiidDdlParsingException(tokens, "Unparsable alter options list (consecutive commas found)"); } foundComma = true; } else if (foundComma) { throw new TeiidDdlParsingException(tokens, "Unparsable alter options list (comma found at end)"); } else { keepParsing = false; } } // must have ending paren if (!tokens.canConsume(R_PAREN)) { throw new TeiidDdlParsingException(tokens, "Unparsable alter options list (right paren not found)"); } return true; } throw new TeiidDdlParsingException(tokens, "Unparsable alter options list (no add, set, or drop found)"); } return false; // not an clause } @Override protected void postProcess( AstNode rootNode ) { } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy