/** * Parses all rows in CREATE TABLE command. * * @param $node_schema schema table belongs to * @param $node_table table being parsed * @param $command command without 'CREATE TABLE ... (' string */ private static function parse_rows(&$node_schema, &$node_table, $command) { $line = $command; $post_columns = false; while (strlen($line) > 0) { $command_end = sql_parser::get_command_end($line, 0); $subCommand = trim(substr($line, 0, $command_end)); if ($post_columns) { $line = self::parse_post_columns($node_table, $subCommand); break; } else { if (substr($line, $command_end, 1) == ')') { $post_columns = true; } } // look for modifier tokens and act accordingly $tokens = preg_split("/[\\s]+/", $subCommand, -1, PREG_SPLIT_NO_EMPTY); // start at 2, first is always name, second is always type for ($i = 2; $i < count($tokens); $i++) { if (strcasecmp($tokens[$i], 'UNIQUE') == 0) { // CREATE TABLE test_table ( // test_table_id varchar(64) PRIMARY KEY, // test_table_col_c varchar(100) UNIQUE NOT NULL // ); // NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index "test_table_pkey" for table "test_table" // NOTICE: CREATE TABLE / UNIQUE will create implicit index "test_table_test_table_col_c_key" for table "test_table" dbsteward::debug("NOTICE: CREATE TABLE with UNIQUE column attribute -- creating implicit index \"" . pgsql8_index::index_name(sql_parser::get_object_name($node_table->get_name()), sql_parser::get_object_name($tokens[0]), 'key') . "\" for table \"" . $node_schema->get_name() . '.' . $node_table->get_name() . "\""); $node_index =& dbx::create_table_index($node_table, pgsql8_index::index_name(sql_parser::get_object_name($node_table['name']), sql_parser::get_object_name($tokens[0]), 'key')); dbx::set_attribute($node_index, 'unique', 'true'); dbx::set_attribute($node_index, 'using', 'btree'); $node_index->addChild('indexDimension', sql_parser::get_object_name($tokens[0]))->addAttribute('name', $tokens[0] . '_unq'); // make sure we don't process this token again unset($tokens[$i]); $tokens = array_merge($tokens); $i--; continue; } // @TODO: other cases? // other cases is how you would fix pgsql8_column::parse_definition() throwing 'column definition parse fail' exceptions } $subCommand = implode(' ', $tokens); self::parse_column_defs($node_schema, $node_table, $subCommand); $line = $command_end >= strlen($line) ? "" : substr($line, $command_end + 1); } $line = trim($line); if (strlen($line) > 0) { throw new exception("Cannot parse CREATE TABLE '" . $node_table['name'] . "' - do not know how to parse '" . $line . "'"); } }
/** * Parses all rows in CREATE TYPE command. * * @param type type being parsed * @param command command without 'CREATE SEQUENCE ... (' string * * @throws ParserException Thrown if problem occurred with parsing of DDL. */ private static function parse_rows($type, $command) { $line = $command; $post_columns = false; while (strlen($line) > 0) { $commandEnd = sql_parser::get_command_end($line, 0); $subCommand = trim(substr($line, 0, $commandEnd)); if ($post_columns) { $line = self::parse_post_columns($type, $subCommand); break; } else { if (substr($line, $commandEnd, 1) == ')') { $post_columns = true; } } self::parse_column_defs($type, $subCommand); $line = $commandEnd >= strlen($line) ? "" : substr($line, $commandEnd + 1); } $line = trim($line); if (strlen($line) > 0) { throw new exception("Cannot parse CREATE TYPE '" . $type->get_name() . "' - do not know how to parse '" . $line . "'"); } }
/** * Parses all rows in ALTER TABLE command. * * @param table table being parsed * @param commands commands * * @throws ParserException Thrown if problem occured while parsing DDL. */ private static function parse_rows(&$db_doc, &$node_schema, &$node_table, $commands) { $line = $commands; $subCommand = null; while (strlen($line) > 0) { $commandEnd = sql_parser::get_command_end($line, 0); $subCommand = trim(substr($line, 0, $commandEnd)); $line = $commandEnd >= strlen($line) ? "" : substr($line, $commandEnd + 1); if (strlen($subCommand) > 0) { if (preg_match(self::PATTERN_ADD_CONSTRAINT_FOREIGN_KEY, $subCommand, $matches) > 0) { $column_name = trim($matches[3]); $constraint_name = trim($matches[1]); $node_constraint = pgsql8_constraint::get_table_constraint($db_doc, $node_table, $constraint_name, true); dbx::set_attribute($node_constraint, 'definition', trim($matches[2])); $subCommand = ""; } } if (preg_match(self::PATTERN_ADD_CONSTRAINT, $subCommand, $matches) > 0) { $constraint_name = trim($matches[1]); $node_constraint = pgsql8_constraint::get_table_constraint($db_doc, $node_table, $constraint_name, true); dbx::set_attribute($node_constraint, 'definition', trim($matches[2])); $subCommand = ""; } if (strlen($subCommand) > 0) { if (preg_match(self::PATTERN_ADD_PRIMARY_KEY, $subCommand, $matches) > 0) { $definition = trim($matches[1]); $column_name = trim($matches[2]); $constraint_name = $node_table['name'] . '_pkey'; dbx::set_attribute($node_table, 'primaryKey', $column_name); $subCommand = ""; } } if (strlen($subCommand) > 0) { if (preg_match(self::PATTERN_ADD_FOREIGN_KEY, $subCommand, $matches) > 0) { $column_name = trim($matches[2]); $constraint_name = pgsql8::identifier_name($node_schema['name'], $node_table['name'], $column_name, '_fkey'); $node_constraint = pgsql8_constraint::get_table_constraint($db_doc, $node_table, $constraint_name, true); dbx::set_attribute($node_constraint, 'definition', trim($matches[1])); $subCommand = ""; } } if (strlen($subCommand) > 0) { if (preg_match(self::PATTERN_SET_DEFAULT, $subCommand, $matches) > 0) { $column_name = trim($matches[1]); $default_value = trim($matches[2]); if ($node_table->contains_column($column_name)) { $node_column =& dbx::get_column($node_table, $column_name); dbx::set_attribute($node_column, 'default', $default_value); } else { throw new exception("Cannot find column '" . $column_name . " 'in table '" . $node_table['name'] . "'"); } $subCommand = ""; } } if (preg_match(self::PATTERN_ALTER_COLUMN_STATISTICS, $subCommand, $matches) > 0) { $column_name = trim($matches[2]); $value = trim($matches[3]); $node_column =& dbx::get_column($node_table, $column_name); dbx::set_attribute($node_column, 'statistics', $value); $subCommand = ""; } if (preg_match(self::PATTERN_CLUSTER_ON, $subCommand, $matches) > 0) { $indexName = trim($matches[1]); dbx::set_attribute($node_column, 'clusterIndexName', $indexName); $subCommand = ""; } if (strlen($subCommand) > 0) { if (preg_match(self::PATTERN_TRIGGER, $subCommand, $matches) > 0) { $triggerName = trim($matches[2]); throw new exception("@TODO: do something with ALTER TABLE ... ENABLE / DISABLE trigger statements"); $subCommand = ""; } } if (strlen($subCommand) > 0) { throw new exception("Don't know how to parse: " . $subCommand); } } }