use of org.hsqldb_voltpatches.VoltXMLElement in project voltdb by VoltDB.
the class DDLCompiler method addColumnToCatalog.
private static void addColumnToCatalog(Table table, VoltXMLElement node, SortedMap<Integer, VoltType> columnTypes, Map<String, Column> columnMap, VoltCompiler compiler) throws VoltCompilerException {
assert node.name.equals("column");
String name = node.attributes.get("name");
String typename = node.attributes.get("valuetype");
String nullable = node.attributes.get("nullable");
String sizeString = node.attributes.get("size");
int index = Integer.valueOf(node.attributes.get("index"));
String defaultvalue = null;
String defaulttype = null;
int defaultFuncID = -1;
// Default Value
for (VoltXMLElement child : node.children) {
if (child.name.equals("default")) {
for (VoltXMLElement inner_child : child.children) {
// Value
if (inner_child.name.equals("value")) {
// There should be only one default value/type.
assert (defaulttype == null);
defaultvalue = inner_child.attributes.get("value");
defaulttype = inner_child.attributes.get("valuetype");
assert (defaulttype != null);
} else if (inner_child.name.equals("function")) {
// There should be only one default value/type.
assert (defaulttype == null);
defaultFuncID = Integer.parseInt(inner_child.attributes.get("function_id"));
defaultvalue = inner_child.attributes.get("name");
defaulttype = inner_child.attributes.get("valuetype");
assert (defaulttype != null);
}
}
}
}
if (defaulttype != null) {
// fyi: Historically, VoltType class initialization errors get reported on this line (?).
defaulttype = Integer.toString(VoltType.typeFromString(defaulttype).getValue());
}
// replace newlines in default values
if (defaultvalue != null) {
defaultvalue = defaultvalue.replace('\n', ' ');
defaultvalue = defaultvalue.replace('\r', ' ');
}
// fyi: Historically, VoltType class initialization errors get reported on this line (?).
VoltType type = VoltType.typeFromString(typename);
columnTypes.put(index, type);
if (defaultFuncID == -1) {
if (defaultvalue != null && (type == VoltType.DECIMAL || type == VoltType.NUMERIC)) {
// Until we support deserializing scientific notation in the EE, we'll
// coerce default values to plain notation here. See ENG-952 for more info.
BigDecimal temp = new BigDecimal(defaultvalue);
defaultvalue = temp.toPlainString();
}
} else {
// Concat function name and function id, format: NAME:ID
// Used by PlanAssembler:getNextInsertPlan().
defaultvalue = defaultvalue + ":" + String.valueOf(defaultFuncID);
}
Column column = table.getColumns().add(name);
// need to set other column data here (default, nullable, etc)
column.setName(name);
column.setIndex(index);
column.setType(type.getValue());
column.setNullable(Boolean.valueOf(nullable));
int size = type.getMaxLengthInBytes();
boolean inBytes = false;
if (node.attributes.containsKey("bytes")) {
inBytes = Boolean.valueOf(node.attributes.get("bytes"));
}
// Determine the length of columns with a variable-length type
if (type.isVariableLength()) {
int userSpecifiedSize = 0;
if (sizeString != null) {
userSpecifiedSize = Integer.parseInt(sizeString);
}
if (userSpecifiedSize == 0) {
// So size specified in the column definition. Either:
// - the user-specified size is zero (unclear how this would happen---
// if someone types VARCHAR(0) HSQL will complain)
// - or the sizeString was null, meaning that the size specifier was
// omitted.
// Choose an appropriate default for the type.
size = type.defaultLengthForVariableLengthType();
} else {
if (userSpecifiedSize < 0 || (inBytes && userSpecifiedSize > VoltType.MAX_VALUE_LENGTH)) {
String msg = type.toSQLString() + " column " + name + " in table " + table.getTypeName() + " has unsupported length " + sizeString;
throw compiler.new VoltCompilerException(msg);
}
if (!inBytes && type == VoltType.STRING) {
if (userSpecifiedSize > VoltType.MAX_VALUE_LENGTH_IN_CHARACTERS) {
String msg = String.format("The size of VARCHAR column %s in table %s greater than %d " + "will be enforced as byte counts rather than UTF8 character counts. " + "To eliminate this warning, specify \"VARCHAR(%d BYTES)\"", name, table.getTypeName(), VoltType.MAX_VALUE_LENGTH_IN_CHARACTERS, userSpecifiedSize);
compiler.addWarn(msg);
inBytes = true;
}
}
if (userSpecifiedSize < type.getMinLengthInBytes()) {
String msg = type.toSQLString() + " column " + name + " in table " + table.getTypeName() + " has length of " + sizeString + " which is shorter than " + type.getMinLengthInBytes() + ", " + "the minimum allowed length for the type.";
throw compiler.new VoltCompilerException(msg);
}
size = userSpecifiedSize;
}
}
column.setInbytes(inBytes);
column.setSize(size);
column.setDefaultvalue(defaultvalue);
if (defaulttype != null)
column.setDefaulttype(Integer.parseInt(defaulttype));
columnMap.put(name, column);
}
use of org.hsqldb_voltpatches.VoltXMLElement in project voltdb by VoltDB.
the class PartitionStatement method processPartitionTable.
private boolean processPartitionTable(String statement) throws VoltCompilerException {
// matches if it is PARTITION TABLE <table> ON COLUMN <column>
Matcher statementMatcher = SQLParser.matchPartitionTable(statement);
if (!statementMatcher.matches()) {
throw m_compiler.new VoltCompilerException(String.format("Invalid PARTITION statement: \"%s\", " + "expected syntax: PARTITION TABLE <table> ON COLUMN <column>", // remove trailing semicolon
statement.substring(0, statement.length() - 1)));
}
// group(1) -> table, group(2) -> column
String tableName = checkIdentifierStart(statementMatcher.group(1), statement);
String columnName = checkIdentifierStart(statementMatcher.group(2), statement);
VoltXMLElement tableXML = m_schema.findChild("table", tableName.toUpperCase());
if (tableXML != null) {
tableXML.attributes.put("partitioncolumn", columnName.toUpperCase());
// Column validity check done by VoltCompiler in post-processing
// mark the table as dirty for the purposes of caching sql statements
m_compiler.markTableAsDirty(tableName);
} else {
throw m_compiler.new VoltCompilerException(String.format("Invalid PARTITION statement: table %s does not exist", tableName));
}
return true;
}
use of org.hsqldb_voltpatches.VoltXMLElement in project voltdb by VoltDB.
the class TestDDLCompiler method testENG_912.
//
// Before the fix for ENG-912, the following schema would work:
// create table tmc (name varchar(32), user varchar(32));
// but this wouldn't:
// create table tmc (name varchar(32), user varchar(32), primary key (name, user));
//
// Changes in HSQL's ParserDQL and ParserBase make this more consistent
//
public void testENG_912() throws HSQLParseException {
String schema = "create table tmc (name varchar(32), user varchar(32), primary key (name, user));";
HSQLInterface hsql = HSQLInterface.loadHsqldb();
hsql.runDDLCommand(schema);
VoltXMLElement xml = hsql.getXMLFromCatalog();
System.out.println(xml);
assertTrue(xml != null);
}
use of org.hsqldb_voltpatches.VoltXMLElement in project voltdb by VoltDB.
the class TestDDLCompiler method testENG_2345.
//
// Before fixing ENG-2345, the VIEW definition wouldn't compile if it were
// containing single quote characters.
//
public void testENG_2345() throws HSQLParseException {
String table = "create table tmc (name varchar(32), user varchar(32), primary key (name, user));";
HSQLInterface hsql = HSQLInterface.loadHsqldb();
hsql.runDDLCommand(table);
String view = "create view v (name , user ) as select name , user from tmc where name = 'name';";
hsql.runDDLCommand(view);
VoltXMLElement xml = hsql.getXMLFromCatalog();
System.out.println(xml);
assertTrue(xml != null);
}
use of org.hsqldb_voltpatches.VoltXMLElement in project voltdb by VoltDB.
the class TestParsedStatements method runSQLTest.
void runSQLTest(String stmtName, String stmtSQL) {
// use HSQLDB to get XML that describes the semantics of the statement
// this is much easier to parse than SQL and is checked against the catalog
VoltXMLElement xmlSQL = null;
try {
xmlSQL = m_hsql.getXMLCompiledStatement(stmtSQL);
} catch (HSQLParseException e) {
e.printStackTrace();
assertTrue(false);
}
// output the xml from hsql to disk for debugging
BuildDirectoryUtils.writeFile("statement-hsql-xml", stmtName + ".xml", xmlSQL.toString(), true);
// get a parsed statement from the xml
AbstractParsedStmt parsedStmt = AbstractParsedStmt.parse(stmtSQL, xmlSQL, null, m_db, null);
// except for "insert" statements that currently do without a joinTree.
if (parsedStmt.m_joinTree != null) {
parsedStmt.m_joinTree.analyzeJoinExpressions(parsedStmt.m_noTableSelectionList);
}
// output a description of the parsed stmt
BuildDirectoryUtils.writeFile("statement-hsql-parsed", stmtName + ".txt", parsedStmt.toString(), true);
assertTrue(parsedStmt.m_noTableSelectionList.isEmpty());
System.out.println(parsedStmt.toString());
}
Aggregations