提交 4656d167 authored 作者: Thomas Mueller's avatar Thomas Mueller

--no commit message

--no commit message
上级 13af88a2
...@@ -37,7 +37,8 @@ Hypersonic SQL or HSQLDB. H2 is built from scratch. ...@@ -37,7 +37,8 @@ Hypersonic SQL or HSQLDB. H2 is built from scratch.
<h3>Version 1.0 (Current)</h3> <h3>Version 1.0 (Current)</h3>
<h3>Version 1.0 / TODO (Build TODO)</h3><ul> <h3>Version 1.0 / TODO (Build TODO)</h3><ul>
<li>New column ID for INFORMATION_SCHEMA.INDEXES, SEQUENCES, USERS, ROLES, RIGHTS, <li>CREATE TABLE AS SELECT .. UNION .. did not work. Fixed.
</li><li>New column ID for INFORMATION_SCHEMA.INDEXES, SEQUENCES, USERS, ROLES, RIGHTS,
FUNCTION_ALIASES, SCHEMATA, VIEWS, CONSTRAINTS, CONSTANTS, DOMAINS, TRIGGERS. FUNCTION_ALIASES, SCHEMATA, VIEWS, CONSTRAINTS, CONSTANTS, DOMAINS, TRIGGERS.
</li><li>If large result sets (backed by a temporary file) where not closed, the file was not deleted. </li><li>If large result sets (backed by a temporary file) where not closed, the file was not deleted.
Now, the default result set type is FETCH_FORWARD. This means temp files are deleted Now, the default result set type is FETCH_FORWARD. This means temp files are deleted
......
...@@ -32,6 +32,7 @@ import org.h2.command.ddl.CreateTrigger; ...@@ -32,6 +32,7 @@ import org.h2.command.ddl.CreateTrigger;
import org.h2.command.ddl.CreateUser; import org.h2.command.ddl.CreateUser;
import org.h2.command.ddl.CreateUserDataType; import org.h2.command.ddl.CreateUserDataType;
import org.h2.command.ddl.CreateView; import org.h2.command.ddl.CreateView;
import org.h2.command.ddl.DeallocateProcedure;
import org.h2.command.ddl.DropConstant; import org.h2.command.ddl.DropConstant;
import org.h2.command.ddl.DropDatabase; import org.h2.command.ddl.DropDatabase;
import org.h2.command.ddl.DropFunctionAlias; import org.h2.command.ddl.DropFunctionAlias;
...@@ -45,11 +46,13 @@ import org.h2.command.ddl.DropUser; ...@@ -45,11 +46,13 @@ import org.h2.command.ddl.DropUser;
import org.h2.command.ddl.DropUserDataType; import org.h2.command.ddl.DropUserDataType;
import org.h2.command.ddl.DropView; import org.h2.command.ddl.DropView;
import org.h2.command.ddl.GrantRevoke; import org.h2.command.ddl.GrantRevoke;
import org.h2.command.ddl.PrepareProcedure;
import org.h2.command.ddl.SetComment; import org.h2.command.ddl.SetComment;
import org.h2.command.ddl.TruncateTable; import org.h2.command.ddl.TruncateTable;
import org.h2.command.dml.BackupCommand; import org.h2.command.dml.BackupCommand;
import org.h2.command.dml.Call; import org.h2.command.dml.Call;
import org.h2.command.dml.Delete; import org.h2.command.dml.Delete;
import org.h2.command.dml.ExecuteProcedure;
import org.h2.command.dml.ExplainPlan; import org.h2.command.dml.ExplainPlan;
import org.h2.command.dml.Insert; import org.h2.command.dml.Insert;
import org.h2.command.dml.Merge; import org.h2.command.dml.Merge;
...@@ -70,6 +73,7 @@ import org.h2.engine.Database; ...@@ -70,6 +73,7 @@ import org.h2.engine.Database;
import org.h2.engine.DbObject; import org.h2.engine.DbObject;
import org.h2.engine.FunctionAlias; import org.h2.engine.FunctionAlias;
import org.h2.engine.Mode; import org.h2.engine.Mode;
import org.h2.engine.Procedure;
import org.h2.engine.Right; import org.h2.engine.Right;
import org.h2.engine.Session; import org.h2.engine.Session;
import org.h2.engine.Setting; import org.h2.engine.Setting;
...@@ -241,14 +245,18 @@ public class Parser { ...@@ -241,14 +245,18 @@ public class Parser {
expected = null; expected = null;
} }
parameters = new ObjectArray(); parameters = new ObjectArray();
int start = lastParseIndex;
currentSelect = null; currentSelect = null;
currentPrepared = null; currentPrepared = null;
prepared = null; prepared = null;
Prepared c = null;
recompileAlways = false; recompileAlways = false;
indexedParameterList = null; indexedParameterList = null;
read(); read();
return parsePrepared();
}
private Prepared parsePrepared() throws SQLException {
int start = lastParseIndex;
Prepared c = null;
String token = currentToken; String token = currentToken;
if(token.length()==0) { if(token.length()==0) {
c = new NoOperation(session); c = new NoOperation(session);
...@@ -291,11 +299,15 @@ public class Parser { ...@@ -291,11 +299,15 @@ public class Parser {
} else if (readIf("DECLARE")) { } else if (readIf("DECLARE")) {
// support for DECLARE GLOBAL TEMPORARY TABLE... // support for DECLARE GLOBAL TEMPORARY TABLE...
c = parseCreate(); c = parseCreate();
} else if (readIf("DEALLOCATE")) {
c = parseDeallocate();
} }
break; break;
case 'E': case 'E':
if (readIf("EXPLAIN")) { if (readIf("EXPLAIN")) {
c = parseExplain(); c = parseExplain();
} else if(readIf("EXECUTE")) {
c = parseExecute();
} }
break; break;
case 'F': case 'F':
...@@ -325,7 +337,7 @@ public class Parser { ...@@ -325,7 +337,7 @@ public class Parser {
break; break;
case 'P': case 'P':
if(readIf("PREPARE")) { if(readIf("PREPARE")) {
c = parsePrepareCommit(); c = parsePrepare();
} }
break; break;
case 'R': case 'R':
...@@ -487,10 +499,29 @@ public class Parser { ...@@ -487,10 +499,29 @@ public class Parser {
return command; return command;
} }
private TransactionCommand parsePrepareCommit() throws SQLException { private Prepared parsePrepare() throws SQLException {
TransactionCommand command = new TransactionCommand(session, TransactionCommand.PREPARE_COMMIT); if(readIf("COMMIT")) {
read("COMMIT"); TransactionCommand command = new TransactionCommand(session, TransactionCommand.PREPARE_COMMIT);
command.setTransactionName(readUniqueIdentifier()); command.setTransactionName(readUniqueIdentifier());
return command;
}
String procedureName = readAliasIdentifier();
if(readIf("(")) {
ObjectArray list = new ObjectArray();
for(int i=0; ; i++) {
Column column = parseColumnForTable("C" + i);
list.add(column);
if(readIf(")")) {
break;
}
read(",");
}
}
read("AS");
Prepared prep = parsePrepared();
PrepareProcedure command = new PrepareProcedure(session);
command.setProcedureName(procedureName);
command.setPrepared(prep);
return command; return command;
} }
...@@ -1062,6 +1093,34 @@ public class Parser { ...@@ -1062,6 +1093,34 @@ public class Parser {
} }
return top; return top;
} }
private Prepared parseExecute() throws SQLException {
ExecuteProcedure command = new ExecuteProcedure(session);
String procedureName = readAliasIdentifier();
Procedure p = session.getProcedure(procedureName);
if(p==null) {
throw Message.getSQLException(Message.FUNCTION_ALIAS_NOT_FOUND_1, procedureName);
}
command.setProcedure(p);
if(readIf("(")) {
for(int i=0; ; i++) {
command.setExpression(i, readExpression());
if(readIf(")")) {
break;
}
read(",");
}
}
return command;
}
private DeallocateProcedure parseDeallocate() throws SQLException {
readIf("PLAN");
String procedureName = readAliasIdentifier();
DeallocateProcedure command = new DeallocateProcedure(session);
command.setProcedureName(procedureName);
return command;
}
private ExplainPlan parseExplain() throws SQLException { private ExplainPlan parseExplain() throws SQLException {
ExplainPlan command = new ExplainPlan(session); ExplainPlan command = new ExplainPlan(session);
...@@ -3382,21 +3441,25 @@ public class Parser { ...@@ -3382,21 +3441,25 @@ public class Parser {
private Prepared parseSet() throws SQLException { private Prepared parseSet() throws SQLException {
if(readIf("AUTOCOMMIT")) { if(readIf("AUTOCOMMIT")) {
readIf("=");
boolean value = readBooleanSetting(); boolean value = readBooleanSetting();
int setting = value ? TransactionCommand.AUTOCOMMIT_TRUE : TransactionCommand.AUTOCOMMIT_FALSE; int setting = value ? TransactionCommand.AUTOCOMMIT_TRUE : TransactionCommand.AUTOCOMMIT_FALSE;
return new TransactionCommand(session, setting); return new TransactionCommand(session, setting);
} else if(readIf("IGNORECASE")) { } else if(readIf("IGNORECASE")) {
readIf("=");
boolean value = readBooleanSetting(); boolean value = readBooleanSetting();
Set command = new Set(session, SetTypes.IGNORECASE); Set command = new Set(session, SetTypes.IGNORECASE);
command.setInt(value ? 1 : 0); command.setInt(value ? 1 : 0);
return command; return command;
} else if(readIf("PASSWORD")) { } else if(readIf("PASSWORD")) {
readIf("=");
AlterUser command = new AlterUser(session); AlterUser command = new AlterUser(session);
command.setType(AlterUser.SET_PASSWORD); command.setType(AlterUser.SET_PASSWORD);
command.setUser(session.getUser()); command.setUser(session.getUser());
command.setPassword(readString()); command.setPassword(readString());
return command; return command;
} else if(readIf("SALT")) { } else if(readIf("SALT")) {
readIf("=");
AlterUser command = new AlterUser(session); AlterUser command = new AlterUser(session);
command.setType(AlterUser.SET_PASSWORD); command.setType(AlterUser.SET_PASSWORD);
command.setUser(session.getUser()); command.setUser(session.getUser());
...@@ -3405,10 +3468,12 @@ public class Parser { ...@@ -3405,10 +3468,12 @@ public class Parser {
command.setHash(readString()); command.setHash(readString());
return command; return command;
} else if(readIf("MODE")) { } else if(readIf("MODE")) {
readIf("=");
Set command = new Set(session, SetTypes.MODE); Set command = new Set(session, SetTypes.MODE);
command.setString(readAliasIdentifier()); command.setString(readAliasIdentifier());
return command; return command;
} else if(readIf("COMPRESS_LOB")) { } else if(readIf("COMPRESS_LOB")) {
readIf("=");
Set command = new Set(session, SetTypes.COMPRESS_LOB); Set command = new Set(session, SetTypes.COMPRESS_LOB);
if(currentTokenType == VALUE) { if(currentTokenType == VALUE) {
command.setString(readString()); command.setString(readString());
...@@ -3417,31 +3482,37 @@ public class Parser { ...@@ -3417,31 +3482,37 @@ public class Parser {
} }
return command; return command;
} else if(readIf("DATABASE")) { } else if(readIf("DATABASE")) {
readIf("=");
read("COLLATION"); read("COLLATION");
return parseSetCollation(); return parseSetCollation();
} else if(readIf("COLLATION")) { } else if(readIf("COLLATION")) {
readIf("=");
return parseSetCollation(); return parseSetCollation();
} else if(readIf("CLUSTER")) { } else if(readIf("CLUSTER")) {
readIf("=");
Set command = new Set(session, SetTypes.CLUSTER); Set command = new Set(session, SetTypes.CLUSTER);
command.setString(readString()); command.setString(readString());
return command; return command;
} else if(readIf("DATABASE_EVENT_LISTENER")) { } else if(readIf("DATABASE_EVENT_LISTENER")) {
readIf("=");
Set command = new Set(session, SetTypes.DATABASE_EVENT_LISTENER); Set command = new Set(session, SetTypes.DATABASE_EVENT_LISTENER);
command.setString(readString()); command.setString(readString());
return command; return command;
} else if(readIf("ALLOW_LITERALS")) { } else if(readIf("ALLOW_LITERALS")) {
readIf("=");
Set command = new Set(session, SetTypes.ALLOW_LITERALS); Set command = new Set(session, SetTypes.ALLOW_LITERALS);
if(readIf("NONE")) { if(readIf("NONE")) {
command.setInt(Constants.ALLOW_LITERALS_NONE); command.setInt(Constants.ALLOW_LITERALS_NONE);
} else if(readIf("ALL")) { } else if(readIf("ALL")) {
command.setInt(Constants.ALLOW_LITERALS_ALL); command.setInt(Constants.ALLOW_LITERALS_ALL);
} else if(readIf("NUMBERS")){ } else if(readIf("NUMBERS")) {
command.setInt(Constants.ALLOW_LITERALS_NUMBERS); command.setInt(Constants.ALLOW_LITERALS_NUMBERS);
} else { } else {
command.setInt(getPositiveInt()); command.setInt(getPositiveInt());
} }
return command; return command;
} else if(readIf("DEFAULT_TABLE_TYPE")) { } else if(readIf("DEFAULT_TABLE_TYPE")) {
readIf("=");
Set command = new Set(session, SetTypes.DEFAULT_TABLE_TYPE); Set command = new Set(session, SetTypes.DEFAULT_TABLE_TYPE);
if(readIf("MEMORY")) { if(readIf("MEMORY")) {
command.setInt(Table.TYPE_MEMORY); command.setInt(Table.TYPE_MEMORY);
...@@ -3452,40 +3523,56 @@ public class Parser { ...@@ -3452,40 +3523,56 @@ public class Parser {
} }
return command; return command;
} else if(readIf("CREATE")) { } else if(readIf("CREATE")) {
readIf("=");
// Derby compatibility (CREATE=TRUE in the database URL) // Derby compatibility (CREATE=TRUE in the database URL)
read(); read();
return new NoOperation(session); return new NoOperation(session);
} else if(readIf("HSQLDB.DEFAULT_TABLE_TYPE")) { } else if(readIf("HSQLDB.DEFAULT_TABLE_TYPE")) {
readIf("=");
read(); read();
return new NoOperation(session); return new NoOperation(session);
} else if(readIf("CACHE_TYPE")) { } else if(readIf("CACHE_TYPE")) {
readIf("=");
read(); read();
return new NoOperation(session); return new NoOperation(session);
} else if(readIf("FILE_LOCK")) { } else if(readIf("FILE_LOCK")) {
readIf("=");
read(); read();
return new NoOperation(session); return new NoOperation(session);
} else if(readIf("STORAGE")) { } else if(readIf("STORAGE")) {
readIf("=");
read(); read();
return new NoOperation(session); return new NoOperation(session);
} else if(readIf("DB_CLOSE_ON_EXIT")) { } else if(readIf("DB_CLOSE_ON_EXIT")) {
readIf("=");
read(); read();
return new NoOperation(session); return new NoOperation(session);
} else if(readIf("ACCESS_MODE_LOG")) { } else if(readIf("ACCESS_MODE_LOG")) {
readIf("=");
read(); read();
return new NoOperation(session); return new NoOperation(session);
} else if(readIf("ASSERT")) { } else if(readIf("ASSERT")) {
readIf("=");
read(); read();
return new NoOperation(session); return new NoOperation(session);
} else if(readIf("ACCESS_MODE_DATA")) { } else if(readIf("ACCESS_MODE_DATA")) {
readIf("=");
read(); read();
return new NoOperation(session); return new NoOperation(session);
} else if(readIf("RECOVER")) { } else if(readIf("RECOVER")) {
readIf("=");
read(); read();
return new NoOperation(session); return new NoOperation(session);
} else if(readIf("SCHEMA")) { } else if(readIf("SCHEMA")) {
readIf("=");
Set command = new Set(session, SetTypes.SCHEMA); Set command = new Set(session, SetTypes.SCHEMA);
command.setString(readAliasIdentifier()); command.setString(readAliasIdentifier());
return command; return command;
} else if(readIf("DATESTYLE")) {
// PostgreSQL compatibility
readIf("=");
read("ISO");
return new NoOperation(session);
} else { } else {
if(isToken("LOGSIZE")) { if(isToken("LOGSIZE")) {
// HSQLDB compatibility // HSQLDB compatibility
...@@ -3494,6 +3581,7 @@ public class Parser { ...@@ -3494,6 +3581,7 @@ public class Parser {
int type = SetTypes.getType(currentToken); int type = SetTypes.getType(currentToken);
if(type >= 0) { if(type >= 0) {
read(); read();
readIf("=");
Set command = new Set(session, type); Set command = new Set(session, type);
command.setExpression(readExpression()); command.setExpression(readExpression());
return command; return command;
......
...@@ -24,7 +24,7 @@ public abstract class Prepared { ...@@ -24,7 +24,7 @@ public abstract class Prepared {
private long modificationId; private long modificationId;
private Command command; private Command command;
private int objectId; private int objectId;
private boolean prepareAlways; protected boolean prepareAlways;
private int currentRowNumber; private int currentRowNumber;
public boolean needRecompile() throws SQLException { public boolean needRecompile() throws SQLException {
......
...@@ -168,7 +168,6 @@ public class CreateTable extends SchemaCommand { ...@@ -168,7 +168,6 @@ public class CreateTable extends SchemaCommand {
} }
private void generateColumnFromQuery() throws SQLException { private void generateColumnFromQuery() throws SQLException {
asQuery.prepare();
int columnCount = asQuery.getColumnCount(); int columnCount = asQuery.getColumnCount();
ObjectArray expressions = asQuery.getExpressions(); ObjectArray expressions = asQuery.getExpressions();
for(int i=0; i<columnCount; i++) { for(int i=0; i<columnCount; i++) {
......
package org.h2.command.ddl;
import java.sql.SQLException;
import org.h2.engine.Session;
public class DeallocateProcedure extends DefineCommand {
private String procedureName;
public DeallocateProcedure(Session session) {
super(session);
}
public int update() throws SQLException {
session.removeProcedure(procedureName);
return 0;
}
public void setProcedureName(String name) {
this.procedureName = name;
}
}
package org.h2.command.ddl;
import java.sql.SQLException;
import org.h2.command.Prepared;
import org.h2.engine.Procedure;
import org.h2.engine.Session;
public class PrepareProcedure extends DefineCommand {
private String procedureName;
private Prepared prepared;
public PrepareProcedure(Session session) {
super(session);
}
public void checkParameters() {
// no not check parameters
}
public int update() throws SQLException {
Procedure proc = new Procedure();
proc.setName(procedureName);
proc.setPrepared(prepared);
prepared.setParameterList(parameters);
prepared.setPrepareAlways(prepareAlways);
prepared.prepare();
session.addProcedure(proc);
return 0;
}
public void setProcedureName(String name) {
this.procedureName = name;
}
public void setPrepared(Prepared prep) {
this.prepared = prep;
}
}
package org.h2.command.dml;
import java.sql.SQLException;
import org.h2.command.Prepared;
import org.h2.engine.Procedure;
import org.h2.engine.Session;
import org.h2.expression.Expression;
import org.h2.expression.Parameter;
import org.h2.result.LocalResult;
import org.h2.util.ObjectArray;
public class ExecuteProcedure extends Prepared {
private ObjectArray expressions = new ObjectArray();
private Procedure procedure;
public ExecuteProcedure(Session session) {
super(session);
}
public void setProcedure(Procedure procedure) {
this.procedure = procedure;
}
public void setExpression(int index, Expression expr) throws SQLException {
expressions.add(index, expr);
}
private void setParameters() throws SQLException {
Prepared prepared = procedure.getPrepared();
ObjectArray params = prepared.getParameters();
for(int i=0; params != null && i<params.size() && i<expressions.size(); i++) {
Expression expr = (Expression) expressions.get(i);
Parameter p = (Parameter) params.get(i);
p.setValue(expr.getValue(session));
}
}
public boolean isQuery() {
Prepared prepared = procedure.getPrepared();
return prepared.isQuery();
}
public int update() throws SQLException {
setParameters();
Prepared prepared = procedure.getPrepared();
return prepared.update();
}
public final LocalResult query(int limit) throws SQLException {
setParameters();
Prepared prepared = procedure.getPrepared();
return prepared.query(limit);
}
public boolean isTransactional() {
return true;
}
public LocalResult queryMeta() throws SQLException {
Prepared prepared = procedure.getPrepared();
return prepared.queryMeta();
}
}
...@@ -170,19 +170,9 @@ public class SelectUnion extends Query { ...@@ -170,19 +170,9 @@ public class SelectUnion extends Query {
if(len != right.getColumnCount()) { if(len != right.getColumnCount()) {
throw Message.getSQLException(Message.COLUMN_COUNT_DOES_NOT_MATCH); throw Message.getSQLException(Message.COLUMN_COUNT_DOES_NOT_MATCH);
} }
}
public void prepare() throws SQLException {
if(Constants.CHECK && (checkPrepared || !checkInit)) {
throw Message.getInternalError("already prepared");
}
checkPrepared = true;
left.prepare();
right.prepare();
ObjectArray le = left.getExpressions(); ObjectArray le = left.getExpressions();
ObjectArray re = right.getExpressions(); ObjectArray re = right.getExpressions();
expressions = new ObjectArray(); expressions = new ObjectArray();
int len = left.getColumnCount();
for(int i=0; i<len; i++) { for(int i=0; i<len; i++) {
Expression l = (Expression)le.get(i); Expression l = (Expression)le.get(i);
Expression r = (Expression)re.get(i); Expression r = (Expression)re.get(i);
...@@ -193,6 +183,15 @@ public class SelectUnion extends Query { ...@@ -193,6 +183,15 @@ public class SelectUnion extends Query {
Expression e = new ExpressionColumn(session.getDatabase(), null, col); Expression e = new ExpressionColumn(session.getDatabase(), null, col);
expressions.add(e); expressions.add(e);
} }
}
public void prepare() throws SQLException {
if(Constants.CHECK && (checkPrepared || !checkInit)) {
throw Message.getInternalError("already prepared");
}
checkPrepared = true;
left.prepare();
right.prepare();
if(orderList != null) { if(orderList != null) {
initOrder(expressions, null, orderList, getColumnCount(), true); initOrder(expressions, null, orderList, getColumnCount(), true);
sort = prepareOrder(expressions, orderList); sort = prepareOrder(expressions, orderList);
......
...@@ -453,7 +453,7 @@ public class Database implements DataHandler { ...@@ -453,7 +453,7 @@ public class Database implements DataHandler {
} }
systemUser = new User(this, 0, Constants.DBA_NAME, true); systemUser = new User(this, 0, Constants.DBA_NAME, true);
mainSchema = new Schema(this, 0, Constants.SCHEMA_MAIN, systemUser, true); mainSchema = new Schema(this, 0, Constants.SCHEMA_MAIN, systemUser, true);
infoSchema = new Schema(this, 0, Constants.SCHEMA_INFORMATION, systemUser, true); infoSchema = new Schema(this, -1, Constants.SCHEMA_INFORMATION, systemUser, true);
schemas.put(mainSchema.getName(), mainSchema); schemas.put(mainSchema.getName(), mainSchema);
schemas.put(infoSchema.getName(), infoSchema); schemas.put(infoSchema.getName(), infoSchema);
publicRole = new Role(this, 0, Constants.PUBLIC_ROLE_NAME, true); publicRole = new Role(this, 0, Constants.PUBLIC_ROLE_NAME, true);
......
...@@ -20,6 +20,7 @@ public class Mode { ...@@ -20,6 +20,7 @@ public class Mode {
public boolean roundWhenConvertToLong ; public boolean roundWhenConvertToLong ;
public boolean lowerCaseIdentifiers; public boolean lowerCaseIdentifiers;
public boolean indexDefinitionInCreateTable; public boolean indexDefinitionInCreateTable;
public boolean systemColumns;
private static final HashMap MODES = new HashMap(); private static final HashMap MODES = new HashMap();
...@@ -41,6 +42,7 @@ public class Mode { ...@@ -41,6 +42,7 @@ public class Mode {
mode = new Mode("PostgreSQL"); mode = new Mode("PostgreSQL");
mode.nullConcatIsNull = true; mode.nullConcatIsNull = true;
mode.roundWhenConvertToLong = true; mode.roundWhenConvertToLong = true;
mode.systemColumns = true;
add(mode); add(mode);
mode = new Mode("MySQL"); mode = new Mode("MySQL");
......
package org.h2.engine;
import org.h2.command.Prepared;
public class Procedure {
private String name;
private Prepared prepared;
public void setName(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setPrepared(Prepared prepared) {
this.prepared = prepared;
}
public Prepared getPrepared() {
return prepared;
}
}
...@@ -58,6 +58,7 @@ public class Session implements SessionInterface { ...@@ -58,6 +58,7 @@ public class Session implements SessionInterface {
private String traceModuleName; private String traceModuleName;
private HashSet unlinkSet; private HashSet unlinkSet;
private int tempViewIndex; private int tempViewIndex;
private HashMap procedures;
public Session() { public Session() {
} }
...@@ -483,4 +484,23 @@ public class Session implements SessionInterface { ...@@ -483,4 +484,23 @@ public class Session implements SessionInterface {
return "TEMP_VIEW_" + tempViewIndex++; return "TEMP_VIEW_" + tempViewIndex++;
} }
public void addProcedure(Procedure procedure) {
if(procedures == null) {
procedures = new HashMap();
}
procedures.put(procedure.getName(), procedure);
}
public void removeProcedure(String name) {
if(procedures != null) {
procedures.remove(name);
}
}
public Procedure getProcedure(String name) {
if(procedures == null) {
return null;
}
return (Procedure) procedures.get(name);
}
} }
...@@ -76,16 +76,28 @@ public class ExpressionColumn extends Expression { ...@@ -76,16 +76,28 @@ public class ExpressionColumn extends Expression {
for (int i = 0; i < columns.length; i++) { for (int i = 0; i < columns.length; i++) {
Column col = columns[i]; Column col = columns[i];
if (columnName.equals(col.getName())) { if (columnName.equals(col.getName())) {
if(this.resolver == null) { mapColumn(resolver, col, level);
queryLevel = level; return;
column = col;
this.resolver = resolver;
break;
} else if(queryLevel==level && this.resolver != resolver) {
throw Message.getSQLException(Message.AMBIGUOUS_COLUMN_NAME_1, columnName);
}
} }
} }
columns = resolver.getSystemColumns();
for (int i = 0; columns != null && i < columns.length; i++) {
Column col = columns[i];
if (columnName.equals(col.getName())) {
mapColumn(resolver, col, level);
return;
}
}
}
private void mapColumn(ColumnResolver resolver, Column col, int level) throws SQLException {
if(this.resolver == null) {
queryLevel = level;
column = col;
this.resolver = resolver;
} else if(queryLevel==level && this.resolver != resolver) {
throw Message.getSQLException(Message.AMBIGUOUS_COLUMN_NAME_1, columnName);
}
} }
public Expression optimize(Session session) throws SQLException { public Expression optimize(Session session) throws SQLException {
......
...@@ -8,10 +8,15 @@ import java.io.IOException; ...@@ -8,10 +8,15 @@ import java.io.IOException;
import java.net.InetAddress; import java.net.InetAddress;
import java.net.ServerSocket; import java.net.ServerSocket;
import java.net.Socket; import java.net.Socket;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException; import java.sql.SQLException;
import java.sql.Timestamp;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashSet; import java.util.HashSet;
import org.h2.engine.Constants;
import org.h2.server.Service; import org.h2.server.Service;
import org.h2.util.MathUtils; import org.h2.util.MathUtils;
import org.h2.util.NetUtils; import org.h2.util.NetUtils;
...@@ -177,5 +182,74 @@ public class PgServer implements Service { ...@@ -177,5 +182,74 @@ public class PgServer implements Service {
public boolean getIfExists() { public boolean getIfExists() {
return ifExists; return ifExists;
} }
public static String getIndexColumn(Connection conn, int indexId, Integer ordinalPosition, Boolean pretty) throws SQLException {
if(ordinalPosition == null || ordinalPosition.intValue() == 0) {
PreparedStatement prep = conn.prepareStatement("select sql from information_schema.indexes where id=?");
prep.setInt(1, indexId);
ResultSet rs = prep.executeQuery();
if(rs.next()) {
return rs.getString(1);
}
return null;
} else {
PreparedStatement prep = conn.prepareStatement("select column_name from information_schema.indexes where id=? and ordinal_position=?");
prep.setInt(1, indexId);
prep.setInt(2, ordinalPosition.intValue());
ResultSet rs = prep.executeQuery();
if(rs.next()) {
return rs.getString(1);
}
return null;
}
}
public static String getCurrentSchema(Connection conn) throws SQLException {
ResultSet rs = conn.createStatement().executeQuery("call schema()");
rs.next();
return rs.getString(1);
}
public static String getEncodingName(int code) throws SQLException {
switch(code) {
case 0:
return "SQL_ASCII";
case 6:
return "UTF8";
case 8:
return "LATIN1";
}
return "UTF8";
}
public static String getVersion() {
return "PostgreSQL 8.1.4 server protocol using H2 " + Constants.getVersion();
}
public static Timestamp getStartTime() {
return new Timestamp(System.currentTimeMillis());
}
public static String getUserById(Connection conn, int id) throws SQLException {
PreparedStatement prep = conn.prepareStatement("SELECT NAME FROM INFORMATION_SCHEMA.USERS WHERE ID=?");
prep.setInt(1, id);
ResultSet rs = prep.executeQuery();
if(rs.next()) {
return rs.getString(1);
}
return null;
}
public static boolean hasDatabasePrivilege(int id, String privilege) {
return false;
}
public static boolean hasTablePrivilege(String table, String privilege) {
return true;
}
public static int getCurrentTid(String table, String id) {
return 1;
}
} }
...@@ -14,6 +14,7 @@ import java.io.InputStream; ...@@ -14,6 +14,7 @@ import java.io.InputStream;
import java.io.InputStreamReader; import java.io.InputStreamReader;
import java.io.OutputStream; import java.io.OutputStream;
import java.io.Reader; import java.io.Reader;
import java.io.StringReader;
import java.net.Socket; import java.net.Socket;
import java.sql.Connection; import java.sql.Connection;
import java.sql.DriverManager; import java.sql.DriverManager;
...@@ -28,63 +29,16 @@ import java.util.HashMap; ...@@ -28,63 +29,16 @@ import java.util.HashMap;
import org.h2.util.JdbcUtils; import org.h2.util.JdbcUtils;
import org.h2.util.ScriptReader; import org.h2.util.ScriptReader;
import org.h2.util.StringUtils;
/** /**
* This class implements a subset of the PostgreSQL protocol as described here:
* http://developer.postgresql.org/pgdocs/postgres/protocol.html
* The PostgreSQL catalog is described here:
* http://www.postgresql.org/docs/7.4/static/view-pg-user.html
* @author Thomas * @author Thomas
*/ */
/*
SELECT NULL AS TABLE_CAT, n.nspname AS TABLE_SCHEM,
c.relname AS TABLE_NAME,
CASE n.nspname LIKE 'pg\\_%' OR n.nspname = 'information_schema' WHEN true THEN
CASE WHEN n.nspname = 'pg_catalog' OR n.nspname = 'information_schema' THEN
CASE c.relkind
WHEN 'r' THEN 'SYSTEM TABLE'
WHEN 'v' THEN 'SYSTEM VIEW'
WHEN 'i' THEN 'SYSTEM INDEX'
ELSE NULL
END
WHEN n.nspname = 'pg_toast' THEN
CASE c.relkind
WHEN 'r' THEN 'SYSTEM TOAST TABLE'
WHEN 'i' THEN 'SYSTEM TOAST INDEX'
ELSE NULL
END
ELSE
CASE c.relkind
WHEN 'r' THEN 'TEMPORARY TABLE'
WHEN 'i' THEN 'TEMPORARY INDEX'
ELSE NULL
END
END
WHEN false THEN
CASE c.relkind
WHEN 'r' THEN 'TABLE'
WHEN 'i' THEN 'INDEX'
WHEN 'S' THEN 'SEQUENCE'
WHEN 'v' THEN 'VIEW'
ELSE NULL
END
ELSE NULL
END AS TABLE_TYPE,
d.description AS REMARKS
FROM pg_catalog.pg_namespace n,
pg_catalog.pg_class c
LEFT JOIN pg_catalog.pg_description d ON (c.oid = d.objoid AND d.objsubid = 0)
LEFT JOIN pg_catalog.pg_class dc ON (d.classoid=dc.oid AND dc.relname='pg_class')
LEFT JOIN pg_catalog.pg_namespace dn ON (dn.oid=dc.relnamespace AND dn.nspname='pg_catalog')
WHERE c.relnamespace = n.oid
AND n.nspname LIKE 'INFORMATION_SCHEMA'
AND (false OR ( c.relkind = 'r' AND n.nspname NOT LIKE 'pg\\_%' AND n.nspname <> 'information_schema' )
OR ( c.relkind = 'r' AND (n.nspname = 'pg_catalog' OR n.nspname = 'information_schema') )
OR ( c.relkind = 'v' AND n.nspname <> 'pg_catalog' AND n.nspname <> 'information_schema' )
OR ( c.relkind = 'v' AND (n.nspname = 'pg_catalog' OR n.nspname = 'information_schema') ) )
ORDER BY TABLE_TYPE,TABLE_SCHEM,TABLE_NAME
*/
public class PgServerThread implements Runnable { public class PgServerThread implements Runnable {
private static final int TYPE_STRING = Types.VARCHAR; private static final int TYPE_STRING = Types.VARCHAR;
private PgServer server; private PgServer server;
...@@ -102,8 +56,8 @@ public class PgServerThread implements Runnable { ...@@ -102,8 +56,8 @@ public class PgServerThread implements Runnable {
private String userName; private String userName;
private String databaseName; private String databaseName;
private int processId; private int processId;
private String clientEncoding; private String clientEncoding = "UTF-8";
private String dateStyle; private String dateStyle = "ISO";
private HashMap prepared = new HashMap(); private HashMap prepared = new HashMap();
private HashMap portals = new HashMap(); private HashMap portals = new HashMap();
...@@ -125,8 +79,7 @@ public class PgServerThread implements Runnable { ...@@ -125,8 +79,7 @@ public class PgServerThread implements Runnable {
server.log("Disconnect"); server.log("Disconnect");
close(); close();
} catch (Exception e) { } catch (Exception e) {
int testing; error("process", e);
e.printStackTrace();
server.logError(e); server.logError(e);
} }
} }
...@@ -198,7 +151,7 @@ public class PgServerThread implements Runnable { ...@@ -198,7 +151,7 @@ public class PgServerThread implements Runnable {
error("CancelRequest", null); error("CancelRequest", null);
} else if(version == 80877103) { } else if(version == 80877103) {
println("SSLRequest"); println("SSLRequest");
error("SSLRequest", null); out.write('N');
} else { } else {
// println("StartupMessage"); // println("StartupMessage");
// println(" version " + version + " (" + (version >> 16) + "." + (version & 0xff) + ")"); // println(" version " + version + " (" + (version >> 16) + "." + (version & 0xff) + ")");
...@@ -228,7 +181,7 @@ public class PgServerThread implements Runnable { ...@@ -228,7 +181,7 @@ public class PgServerThread implements Runnable {
String password = readString(); String password = readString();
// println(" password: " + password); // println(" password: " + password);
try { try {
conn = DriverManager.getConnection("jdbc:h2:" + databaseName, userName, password); conn = DriverManager.getConnection("jdbc:h2:" + databaseName + ";MODE=PostgreSQL", userName, password);
initDb(); initDb();
sendAuthenticationOk(); sendAuthenticationOk();
} catch(SQLException e) { } catch(SQLException e) {
...@@ -365,27 +318,32 @@ public class PgServerThread implements Runnable { ...@@ -365,27 +318,32 @@ public class PgServerThread implements Runnable {
case 'Q': { case 'Q': {
// println("Query"); // println("Query");
String query = readString(); String query = readString();
if(query.startsWith("select oid, typbasetype from pg_type where typname =")) { ScriptReader reader = new ScriptReader(new StringReader(query));
query = "select oid, typbasetype from pg_catalog.pg_type WHERE 1=0"; while(true) {
} else if(query.startsWith("select current_schema()")) { try {
query = "CALL SCHEMA()"; String s = reader.readStatement();
} else if(query.startsWith("show max_identifier_length")) { if(s == null) {
query = "CALL 63"; break;
} }
try { s = getSQL(s);
Statement stat = conn.createStatement(); Statement stat = conn.createStatement();
boolean result = stat.execute(query); boolean result = stat.execute(s);
if(result) { if(result) {
ResultSet rs = stat.getResultSet(); ResultSet rs = stat.getResultSet();
sendResultSet(rs); ResultSetMetaData meta = rs.getMetaData();
} else { sendRowDescription(meta);
int testing; while(rs.next()) {
System.out.println("not a query"); sendDataRow(null, rs);
// todo }
sendCommandComplete(s, 0);
} else {
sendCommandComplete(s, stat.getUpdateCount());
}
} catch(SQLException e) {
sendErrorResponse(e);
} }
} catch(SQLException e) {
e.printStackTrace();
} }
sendReadyForQuery('I');
break; break;
} }
case 'X': { case 'X': {
...@@ -399,6 +357,29 @@ public class PgServerThread implements Runnable { ...@@ -399,6 +357,29 @@ public class PgServerThread implements Runnable {
} }
private String getSQL(String s) { private String getSQL(String s) {
if(s.startsWith("show max_identifier_length")) {
s = "CALL 63";
} else if(s.startsWith("set client_encoding to")) {
s = "set DATESTYLE ISO";
} else if(s.startsWith("BEGIN")) {
s = "set DATESTYLE ISO";
}
s = StringUtils.replaceAll(s, "FROM pg_database", "FROM pg_catalog.pg_database");
s = StringUtils.replaceAll(s, "FROM pg_user", "FROM pg_catalog.pg_user");
s = StringUtils.replaceAll(s, "FROM pg_settings", "FROM pg_catalog.pg_settings");
s = StringUtils.replaceAll(s, "FROM pg_database", "FROM pg_catalog.pg_database");
s = StringUtils.replaceAll(s, "JOIN pg_tablespace", "JOIN pg_catalog.pg_tablespace");
s = StringUtils.replaceAll(s, "FROM pg_tablespace", "FROM pg_catalog.pg_tablespace");
s = StringUtils.replaceAll(s, "FROM pg_class", "FROM pg_catalog.pg_class");
s = StringUtils.replaceAll(s, "from pg_class", "from pg_catalog.pg_class");
s = StringUtils.replaceAll(s, ", pg_namespace", ", pg_catalog.pg_namespace");
s = StringUtils.replaceAll(s, "JOIN pg_namespace", "JOIN pg_catalog.pg_namespace");
s = StringUtils.replaceAll(s, "FROM pg_authid", "FROM pg_catalog.pg_authid");
s = StringUtils.replaceAll(s, "from pg_type", "from pg_catalog.pg_type");
s = StringUtils.replaceAll(s, "join pg_attrdef", "join pg_catalog.pg_attrdef");
s = StringUtils.replaceAll(s, "i.indkey[ia.attnum-1]", "0");
s = StringUtils.replaceAll(s, "current_user", "USER()");
s = StringUtils.replaceAll(s, "E'", "'"); // VALUES (E'2'[*], E'Test')
if(s.indexOf('$') > 0) { if(s.indexOf('$') > 0) {
int todoDontReplaceInQuoted; int todoDontReplaceInQuoted;
s = s.replace('$', '?'); s = s.replace('$', '?');
...@@ -527,7 +508,7 @@ public class PgServerThread implements Runnable { ...@@ -527,7 +508,7 @@ public class PgServerThread implements Runnable {
startMessage('T'); startMessage('T');
writeShort(columns); writeShort(columns);
for(int i=0; i<columns; i++) { for(int i=0; i<columns; i++) {
writeString(names[i]); writeString(names[i].toLowerCase());
writeInt(0); // object ID writeInt(0); // object ID
writeShort(0); // attribute number of the column writeShort(0); // attribute number of the column
writeInt(getType(types[i])); // data type writeInt(getType(types[i])); // data type
...@@ -596,47 +577,48 @@ public class PgServerThread implements Runnable { ...@@ -596,47 +577,48 @@ public class PgServerThread implements Runnable {
} }
stat.execute(sql); stat.execute(sql);
} }
reader.close();
} }
private void sendResultSet(ResultSet rs) throws SQLException, IOException { // private void sendResultSet(ResultSet rs) throws SQLException, IOException {
ResultSetMetaData meta = rs.getMetaData(); // ResultSetMetaData meta = rs.getMetaData();
int columnCount = meta.getColumnCount(); // int columnCount = meta.getColumnCount();
// // //
startMessage('T'); // startMessage('T');
writeShort(columnCount); // writeShort(columnCount);
for(int i=0; i<columnCount; i++) { // for(int i=0; i<columnCount; i++) {
writeString(meta.getColumnName(i + 1)); // writeString(meta.getColumnName(i + 1));
writeInt(0); // table id // writeInt(0); // table id
writeShort(0); // column id // writeShort(0); // column id
writeInt(0); // data type id // writeInt(0); // data type id
writeShort(26); // data type size (see pg_type.typlen) // writeShort(26); // data type size (see pg_type.typlen)
writeInt(4); // type modifier (see pg_attribute.atttypmod) // writeInt(4); // type modifier (see pg_attribute.atttypmod)
writeShort(0); // format code 0=text, 1=binary // writeShort(0); // format code 0=text, 1=binary
} // }
sendMessage(); // sendMessage();
while(rs.next()) { // while(rs.next()) {
// DataRow // // DataRow
startMessage('D'); // startMessage('D');
writeShort(columnCount); // writeShort(columnCount);
for(int i=0; i<columnCount; i++) { // for(int i=0; i<columnCount; i++) {
String v = rs.getString(i + 1); // String v = rs.getString(i + 1);
if(v == null) { // if(v == null) {
writeInt(-1); // writeInt(-1);
} else { // } else {
byte[] data = v.getBytes(); // byte[] data = v.getBytes();
writeInt(data.length); // writeInt(data.length);
write(data); // write(data);
} // }
} // }
sendMessage(); // sendMessage();
} // }
//
// CommandComplete // // CommandComplete
startMessage('C'); // startMessage('C');
writeString("SELECT"); // writeString("SELECT");
sendMessage(); // sendMessage();
sendReadyForQuery('I'); // sendReadyForQuery('I');
} // }
public void close() { public void close() {
try { try {
......
drop schema if exists pg_catalog; drop schema if exists pg_catalog;
create schema pg_catalog; create schema pg_catalog;
create view pg_catalog.pg_type(oid, typlen, typbasetype, typname, typnamespace) as create table pg_catalog.pg_namespace -- (oid, nspname)
as
select select
id oid,
cast(schema_name as varchar_ignorecase) nspname
from information_schema.schemata;
create table pg_catalog.pg_type(
oid int,
typname varchar_ignorecase,
typnamespace int,
typlen int,
typbasetype int);
insert into pg_catalog.pg_type
select
data_type oid, data_type oid,
precision, cast(type_name as varchar_ignorecase) typname,
data_type, (select oid from pg_catalog.pg_namespace where nspname = 'pg_catalog') typnamespace,
cast(type_name as varchar_ignorecase) typbasetype, -1 typlen,
select id from information_schema.schemata where schema_name='PG_CATALOG' 0 typbasetype
from information_schema.type_info from information_schema.type_info;
union select
1111, insert into pg_catalog.pg_type values(
64, 1111,
1111,
'name', 'name',
select id from information_schema.schemata where schema_name='PG_CATALOG' (select oid from pg_catalog.pg_namespace where nspname = 'pg_catalog'),
from dual; -1,
0
);
create view pg_catalog.pg_namespace(oid, nspname) as create table pg_catalog.pg_class -- (oid, relname, relnamespace, relkind, relam, reltuples, relpages, relhasrules, relhasoids)
select id, cast(schema_name as varchar_ignorecase) as
from information_schema.schemata; select
id oid,
cast(table_name as varchar_ignorecase) relname,
(select id from information_schema.schemata where schema_name = table_schema) relnamespace,
case table_type when 'TABLE' then 'r' else 'v' end relkind,
0 relam,
cast(0 as float) reltuples,
0 relpages,
false relhasrules,
false relhasoids
from information_schema.tables
union all
select
id oid,
cast(index_name as varchar_ignorecase) relname,
(select id from information_schema.schemata where schema_name = table_schema) relnamespace,
'i' relkind,
0 relam,
cast(0 as float) reltuples,
0 relpages,
false relhasrules,
false relhasoids
from information_schema.indexes;
create view pg_catalog.pg_class(oid, relname, relnamespace, relkind) as create table pg_catalog.pg_description -- (objoid, objsubid, classoid, description)
as
select select
id, id objoid,
cast(table_name as varchar_ignorecase), 0 objsubid,
(select id from information_schema.schemata where schema_name = table_schema), -1 classoid,
case table_type when 'TABLE' then 'r' else 'v' end cast('' as varchar_ignorecase) description
from information_schema.tables;
create view pg_catalog.pg_description(objoid, objsubid, classoid, description) as
select id, 0, -1, cast('' as varchar_ignorecase)
from information_schema.tables where 1=0; from information_schema.tables where 1=0;
create view pg_catalog.pg_attrdef(oid, adsrc, adrelid, adnum) as create table pg_catalog.pg_proc(
select id, 0, 0, 0 oid int,
proname varchar_ignorecase
);
create table pg_catalog.pg_trigger(
oid int,
tgconstrrelid int,
tgfoid int,
tgargs int,
tgnargs int,
tgdeferrable boolean,
tginitdeferred boolean,
tgconstrname varchar_ignorecase,
tgrelid int
);
create table pg_catalog.pg_attrdef -- (oid, adsrc, adrelid, adnum)
as
select
id oid,
0 adsrc,
0 adrelid,
0 adnum
from information_schema.tables where 1=0; from information_schema.tables where 1=0;
create view pg_catalog.pg_attribute(oid, attname, atttypid, attnotnull, atttypmod, create table pg_catalog.pg_attribute -- (oid, attrelid, attname, atttypid, attlen, attnum, atttypmod, attnotnull, attisdropped, atthasdef)
attlen, attnum, attrelid, attisdropped) as as
select select
t.id*10000 + ordinal_position, column_name, data_type, false, -1, t.id*10000 + c.ordinal_position oid,
numeric_precision, ordinal_position, t.id, false t.id attrelid,
from c.column_name attname,
information_schema.tables t, data_type atttypid,
information_schema.columns c -1 attlen,
c.ordinal_position attnum,
-1 atttypmod,
false attnotnull,
false attisdropped,
false atthasdef
from information_schema.tables t, information_schema.columns c
where t.table_name = c.table_name where t.table_name = c.table_name
and t.table_schema = c.table_schema
union all
select
1000000 + t.id*10000 + c.ordinal_position oid,
i.id attrelid,
c.column_name attname,
data_type atttypid,
-1 attlen,
c.ordinal_position attnum,
-1 atttypmod,
false attnotnull,
false attisdropped,
false atthasdef
from information_schema.tables t, information_schema.indexes i, information_schema.columns c
where t.table_name = i.table_name
and t.table_schema = i.table_schema
and t.table_name = c.table_name
and t.table_schema = c.table_schema; and t.table_schema = c.table_schema;
create table pg_catalog.pg_index -- (oid, indexrelid, indrelid, indisclustered, indisunique, indisprimary, indexprs, indkey)
as
select
i.id oid,
i.id indexrelid,
t.id indrelid,
false indisclustered,
not non_unique indisunique,
primary_key indisprimary,
cast(null as varchar_ignorecase) indexprs,
cast(0 as array) indkey
from information_schema.indexes i, information_schema.tables t
where i.table_schema = t.table_schema
and i.table_name = t.table_name
and i.ordinal_position = 1;
drop alias if exists pg_get_indexdef;
create alias pg_get_indexdef for "org.h2.server.pg.PgServer.getIndexColumn";
drop alias if exists version;
create alias version for "org.h2.server.pg.PgServer.getVersion";
drop alias if exists current_schema;
create alias current_schema for "org.h2.server.pg.PgServer.getCurrentSchema";
drop alias if exists pg_encoding_to_char;
create alias pg_encoding_to_char for "org.h2.server.pg.PgServer.getEncodingName";
drop alias if exists pg_postmaster_start_time;
create alias pg_postmaster_start_time for "org.h2.server.pg.PgServer.getStartTime";
drop alias if exists pg_get_userbyid;
create alias pg_get_userbyid for "org.h2.server.pg.PgServer.getUserById";
drop alias if exists has_database_privilege;
create alias has_database_privilege for "org.h2.server.pg.PgServer.hasDatabasePrivilege";
drop alias if exists has_table_privilege;
create alias has_table_privilege for "org.h2.server.pg.PgServer.hasTablePrivilege";
drop alias if exists currtid2;
create alias currtid2 for "org.h2.server.pg.PgServer.getCurrentTid";
create table pg_catalog.pg_database(
oid int,
datname varchar_ignorecase,
encoding int,
datlastsysoid int,
datallowconn boolean,
datconfig array, -- text[]
datacl array, -- aclitem[]
datdba int,
dattablespace int
);
insert into pg_catalog.pg_database values(
0, -- oid
'postgres', -- datname
6, -- encoding, UTF8
100000, -- datlastsysoid
true, -- datallowconn
null, -- datconfig
null, -- datacl
select min(id) from information_schema.users where admin=true, -- datdba
0 -- dattablespace
);
create table pg_catalog.pg_tablespace(
oid int,
spcname varchar_ignorecase,
spclocation varchar_ignorecase,
spcowner int,
spcacl array -- aclitem[]
);
insert into pg_catalog.pg_tablespace values(
0,
'main', -- spcname
'?', -- spclocation
0, -- spcowner,
null -- spcacl
);
create table pg_catalog.pg_settings(
oid int,
name varchar_ignorecase,
setting varchar_ignorecase
);
insert into pg_catalog.pg_settings values
(0, 'autovacuum', 'on'),
(1, 'stats_start_collector', 'on'),
(2, 'stats_row_level', 'on');
create table pg_catalog.pg_user(
oid int,
usename varchar_ignorecase,
usecreatedb boolean,
usesuper boolean);
insert into pg_catalog.pg_user select
id oid,
cast(name as varchar_ignorecase) usename,
true usecreatedb,
true usesuper
from information_schema.users;
create table pg_catalog.pg_authid(
oid int,
rolname varchar_ignorecase,
rolsuper boolean,
rolinherit boolean,
rolcreaterole boolean,
rolcreatedb boolean,
rolcatupdate boolean,
rolcanlogin boolean,
rolconnlimit boolean,
rolpassword boolean,
rolvaliduntil timestamp, -- timestamptz
rolconfig array -- text[]
);
create table pg_catalog.pg_am(oid int, amname varchar_ignorecase);
insert into pg_catalog.pg_am values(0, 'btree');
insert into pg_catalog.pg_am values(1, 'hash');
SELECT SELECT
NULL AS TABLE_CAT, NULL AS TABLE_CAT,
n.nspname AS TABLE_SCHEM, n.nspname AS TABLE_SCHEM,
...@@ -79,4 +284,3 @@ SELECT ...@@ -79,4 +284,3 @@ SELECT
AND n.nspname = 'PUBLIC' AND n.nspname = 'PUBLIC'
AND ct.relname = 'TEST' AND ct.relname = 'TEST'
ORDER BY NON_UNIQUE, TYPE, INDEX_NAME, ORDINAL_POSITION ; ORDER BY NON_UNIQUE, TYPE, INDEX_NAME, ORDINAL_POSITION ;
...@@ -13,6 +13,7 @@ public interface ColumnResolver { ...@@ -13,6 +13,7 @@ public interface ColumnResolver {
String getTableAlias(); String getTableAlias();
Column[] getColumns(); Column[] getColumns();
Column[] getSystemColumns();
String getSchemaName(); String getSchemaName();
Value getValue(Column column) throws SQLException; Value getValue(Column column) throws SQLException;
TableFilter getTableFilter(); TableFilter getTableFilter();
......
...@@ -140,6 +140,7 @@ public class MetaTable extends Table { ...@@ -140,6 +140,7 @@ public class MetaTable extends Table {
"PAGES INT", "PAGES INT",
"FILTER_CONDITION", "FILTER_CONDITION",
"REMARKS", "REMARKS",
"SQL",
"ID INT" "ID INT"
}); });
indexColumnName = "TABLE_NAME"; indexColumnName = "TABLE_NAME";
...@@ -512,14 +513,17 @@ public class MetaTable extends Table { ...@@ -512,14 +513,17 @@ public class MetaTable extends Table {
public ObjectArray generateRows(Session session, SearchRow first, SearchRow last) throws SQLException { public ObjectArray generateRows(Session session, SearchRow first, SearchRow last) throws SQLException {
Value indexFrom = null, indexTo = null; Value indexFrom = null, indexTo = null;
if(indexColumn >= 0) {
if(first != null) { int testing;
indexFrom = first.getValue(indexColumn); // if(indexColumn >= 0) {
} // if(first != null) {
if(last != null) { // indexFrom = first.getValue(indexColumn);
indexTo = last.getValue(indexColumn); // }
} // if(last != null) {
} // indexTo = last.getValue(indexColumn);
// }
// }
ObjectArray rows = new ObjectArray(); ObjectArray rows = new ObjectArray();
String catalog = identifier(database.getShortName()); String catalog = identifier(database.getShortName());
switch(type) { switch(type) {
...@@ -627,6 +631,7 @@ public class MetaTable extends Table { ...@@ -627,6 +631,7 @@ public class MetaTable extends Table {
"0", // PAGES "0", // PAGES
"", // FILTER_CONDITION "", // FILTER_CONDITION
replaceNullWithEmpty(index.getComment()), // REMARKS replaceNullWithEmpty(index.getComment()), // REMARKS
index.getSQL(), // SQL
"" + index.getId() // ID "" + index.getId() // ID
}); });
} }
......
...@@ -44,4 +44,8 @@ public class SingleColumnResolver implements ColumnResolver { ...@@ -44,4 +44,8 @@ public class SingleColumnResolver implements ColumnResolver {
return null; return null;
} }
public Column[] getSystemColumns() {
return null;
}
} }
...@@ -8,6 +8,7 @@ import java.sql.SQLException; ...@@ -8,6 +8,7 @@ import java.sql.SQLException;
import org.h2.command.dml.Select; import org.h2.command.dml.Select;
import org.h2.engine.Constants; import org.h2.engine.Constants;
import org.h2.engine.Mode;
import org.h2.engine.Right; import org.h2.engine.Right;
import org.h2.engine.Session; import org.h2.engine.Session;
import org.h2.expression.ConditionAndOr; import org.h2.expression.ConditionAndOr;
...@@ -21,6 +22,7 @@ import org.h2.result.SearchRow; ...@@ -21,6 +22,7 @@ import org.h2.result.SearchRow;
import org.h2.util.ObjectArray; import org.h2.util.ObjectArray;
import org.h2.util.StringUtils; import org.h2.util.StringUtils;
import org.h2.value.Value; import org.h2.value.Value;
import org.h2.value.ValueInt;
/** /**
* @author Thomas * @author Thomas
...@@ -514,6 +516,20 @@ public class TableFilter implements ColumnResolver { ...@@ -514,6 +516,20 @@ public class TableFilter implements ColumnResolver {
return table.getColumns(); return table.getColumns();
} }
public Column[] getSystemColumns() {
if(!Mode.getCurrentMode().systemColumns) {
return null;
}
Column[] sys = new Column[3];
sys[0] = new Column("oid", Value.INT, ValueInt.PRECISION, 0);
sys[0].setTable(table, 0);
sys[1] = new Column("ctid", Value.STRING, ValueInt.PRECISION, 0);
sys[1].setTable(table, 0);
sys[2] = new Column("CTID", Value.STRING, ValueInt.PRECISION, 0);
sys[2].setTable(table, 0);
return sys;
}
public Value getValue(Column column) throws SQLException { public Value getValue(Column column) throws SQLException {
if(Constants.INDEX_LOOKUP_NEW) { if(Constants.INDEX_LOOKUP_NEW) {
if(currentSearchRow == null) { if(currentSearchRow == null) {
......
...@@ -21,6 +21,14 @@ public class ScriptReader { ...@@ -21,6 +21,14 @@ public class ScriptReader {
this.reader = reader; this.reader = reader;
} }
public void close() throws SQLException {
try {
reader.close();
} catch (IOException e) {
throw Message.convertIOException(e, null);
}
}
private int read() throws SQLException { private int read() throws SQLException {
try { try {
return reader.read(); return reader.read();
......
...@@ -77,7 +77,7 @@ public class DataType { ...@@ -77,7 +77,7 @@ public class DataType {
); );
add(Value.STRING, Types.VARCHAR, "String", add(Value.STRING, Types.VARCHAR, "String",
createString(true), createString(true),
new String[]{"VARCHAR", "VARCHAR2", "NVARCHAR", "NVARCHAR2", "VARCHAR_CASESENSITIVE", "CHARACTER VARYING"} new String[]{"VARCHAR", "VARCHAR2", "NVARCHAR", "NVARCHAR2", "VARCHAR_CASESENSITIVE", "CHARACTER VARYING", "TID"}
); );
add(Value.STRING, Types.LONGVARCHAR, "String", add(Value.STRING, Types.LONGVARCHAR, "String",
createString(true), createString(true),
......
...@@ -555,7 +555,9 @@ public class ValueLob extends Value { ...@@ -555,7 +555,9 @@ public class ValueLob extends Value {
String[] list = FileUtils.listFiles(dir); String[] list = FileUtils.listFiles(dir);
for(int i=0; i<list.length; i++) { for(int i=0; i<list.length; i++) {
String name = list[i]; String name = list[i];
if(name.startsWith(prefix+"." + tableId) && name.endsWith(".lob.db")) { int testing;
// if(name.startsWith(prefix+ "." + tableId + ".") && name.endsWith(".lob.db")) {
if(name.startsWith(prefix+ "." + tableId + ".") && name.endsWith(".lob.db")) {
deleteFile(handler, name); deleteFile(handler, name);
} }
} }
......
...@@ -94,6 +94,15 @@ java -Xmx512m -Xrunhprof:cpu=samples,depth=8 org.h2.tools.RunScript -url jdbc:h2 ...@@ -94,6 +94,15 @@ java -Xmx512m -Xrunhprof:cpu=samples,depth=8 org.h2.tools.RunScript -url jdbc:h2
/* /*
pg_catalog with views
oid (object identifier)
The unique object identifier of a row. PostgreSQL automatically adds this 4-byte number to all rows. It is never re-used within the same table.
ctid (tuple identifier)
The identifier which describes the physical location of the tuple within the database. A pair of numbers are represented by the ctid: the block number, and tuple index within that block.
make sure INDEX_LOOKUP_NEW = is true by default. make sure INDEX_LOOKUP_NEW = is true by default.
Test Console (batch, javaw, different platforms) Test Console (batch, javaw, different platforms)
test with openoffice (metadata changes) test with openoffice (metadata changes)
......
...@@ -199,12 +199,15 @@ public class TestCases extends TestBase { ...@@ -199,12 +199,15 @@ public class TestCases extends TestBase {
rs.next(); rs.next();
check("Hello", rs.getString(1)); check("Hello", rs.getString(1));
checkFalse(rs.next()); checkFalse(rs.next());
rs = stat.executeQuery("SELECT ? FROM DUAL UNION ALL SELECT ? FROM DUAL {1: 'Hello', 2:'World' }");
rs.next(); int todo;
check("Hello", rs.getString(1)); // rs = stat.executeQuery("SELECT ? FROM DUAL UNION ALL SELECT ? FROM DUAL {1: 'Hello', 2:'World' }");
rs.next(); // rs.next();
check("World", rs.getString(1)); // check("Hello", rs.getString(1));
checkFalse(rs.next()); // rs.next();
// check("World", rs.getString(1));
// checkFalse(rs.next());
conn.close(); conn.close();
} }
......
...@@ -48,6 +48,7 @@ public class TestScriptSimple extends TestBase { ...@@ -48,6 +48,7 @@ public class TestScriptSimple extends TestBase {
conn.createStatement().execute(sql); conn.createStatement().execute(sql);
} }
} }
is.close();
conn.close(); conn.close();
} }
......
...@@ -778,16 +778,16 @@ select * from test; ...@@ -778,16 +778,16 @@ select * from test;
> null null <empty> > null null <empty>
> rows: 1 > rows: 1
select * from information_schema.domains; select DOMAIN_NAME, COLUMN_DEFAULT, IS_NULLABLE, DATA_TYPE, PRECISION, SCALE, TYPE_NAME, SELECTIVITY, CHECK_CONSTRAINT, REMARKS, SQL from information_schema.domains;
> DOMAIN_CATALOG DOMAIN_SCHEMA DOMAIN_NAME COLUMN_DEFAULT IS_NULLABLE DATA_TYPE PRECISION SCALE TYPE_NAME SELECTIVITY CHECK_CONSTRAINT REMARKS SQL > DOMAIN_NAME COLUMN_DEFAULT IS_NULLABLE DATA_TYPE PRECISION SCALE TYPE_NAME SELECTIVITY CHECK_CONSTRAINT REMARKS SQL
> -------------- ------------- ----------- -------------- ----------- --------- ---------- ----- --------- ----------- --------------------------------------------------------------- ------- ------------------------------------------------------------------------------------------------------------------------------ > ----------- -------------- ----------- --------- ---------- ----- --------- ----------- --------------------------------------------------------------- ------- ------------------------------------------------------------------------------------------------------------------------------
> SCRIPT PUBLIC EMAIL YES 12 200 0 VARCHAR 50 (POSITION('@', VALUE) > 1) CREATE DOMAIN EMAIL AS VARCHAR(200) CHECK (POSITION('@', VALUE) > 1) > EMAIL YES 12 200 0 VARCHAR 50 (POSITION('@', VALUE) > 1) CREATE DOMAIN EMAIL AS VARCHAR(200) CHECK (POSITION('@', VALUE) > 1)
> SCRIPT PUBLIC GMAIL '@gmail.com' YES 12 200 0 VARCHAR 50 ((POSITION('@', VALUE) > 1) AND (POSITION('gmail', VALUE) > 1)) CREATE DOMAIN GMAIL AS VARCHAR(200) DEFAULT '@gmail.com' CHECK ((POSITION('@', VALUE) > 1) AND (POSITION('gmail', VALUE) > 1)) > GMAIL '@gmail.com' YES 12 200 0 VARCHAR 50 ((POSITION('@', VALUE) > 1) AND (POSITION('gmail', VALUE) > 1)) CREATE DOMAIN GMAIL AS VARCHAR(200) DEFAULT '@gmail.com' CHECK ((POSITION('@', VALUE) > 1) AND (POSITION('gmail', VALUE) > 1))
> SCRIPT PUBLIC STRING '' NO 12 255 0 VARCHAR 50 CREATE DOMAIN STRING AS VARCHAR(255) DEFAULT '' NOT NULL > STRING '' NO 12 255 0 VARCHAR 50 CREATE DOMAIN STRING AS VARCHAR(255) DEFAULT '' NOT NULL
> SCRIPT PUBLIC STRING1 YES 12 2147483647 0 VARCHAR 50 CREATE DOMAIN STRING1 AS VARCHAR > STRING1 YES 12 2147483647 0 VARCHAR 50 CREATE DOMAIN STRING1 AS VARCHAR
> SCRIPT PUBLIC STRING2 NO 12 2147483647 0 VARCHAR 50 CREATE DOMAIN STRING2 AS VARCHAR NOT NULL > STRING2 NO 12 2147483647 0 VARCHAR 50 CREATE DOMAIN STRING2 AS VARCHAR NOT NULL
> SCRIPT PUBLIC STRING3 '<empty>' YES 12 2147483647 0 VARCHAR 50 CREATE DOMAIN STRING3 AS VARCHAR DEFAULT '<empty>' > STRING3 '<empty>' YES 12 2147483647 0 VARCHAR 50 CREATE DOMAIN STRING3 AS VARCHAR DEFAULT '<empty>'
> SCRIPT PUBLIC STRING_X '<empty>' YES 12 2147483647 0 VARCHAR 50 CREATE DOMAIN STRING_X AS VARCHAR DEFAULT '<empty>' > STRING_X '<empty>' YES 12 2147483647 0 VARCHAR 50 CREATE DOMAIN STRING_X AS VARCHAR DEFAULT '<empty>'
> rows: 7 > rows: 7
script nodata nopasswords nosettings; script nodata nopasswords nosettings;
...@@ -910,11 +910,11 @@ CREATE CONSTANT IF NOT EXISTS ONE VALUE 1; ...@@ -910,11 +910,11 @@ CREATE CONSTANT IF NOT EXISTS ONE VALUE 1;
CREATE CONSTANT CONST.ONE VALUE 1; CREATE CONSTANT CONST.ONE VALUE 1;
> ok > ok
SELECT * FROM INFORMATION_SCHEMA.CONSTANTS; SELECT CONSTANT_SCHEMA, CONSTANT_NAME, DATA_TYPE, REMARKS, SQL FROM INFORMATION_SCHEMA.CONSTANTS;
> CONSTANT_CATALOG CONSTANT_SCHEMA CONSTANT_NAME DATA_TYPE REMARKS SQL > CONSTANT_SCHEMA CONSTANT_NAME DATA_TYPE REMARKS SQL
> ---------------- --------------- ------------- --------- ------- --- > --------------- ------------- --------- ------- ---
> SCRIPT CONST ONE 4 1 > CONST ONE 4 1
> SCRIPT PUBLIC ONE 4 Eins 1 > PUBLIC ONE 4 Eins 1
> rows: 2 > rows: 2
SELECT ONE, CONST.ONE FROM DUAL; SELECT ONE, CONST.ONE FROM DUAL;
...@@ -929,10 +929,10 @@ COMMENT ON CONSTANT ONE IS NULL; ...@@ -929,10 +929,10 @@ COMMENT ON CONSTANT ONE IS NULL;
DROP SCHEMA CONST; DROP SCHEMA CONST;
> ok > ok
SELECT * FROM INFORMATION_SCHEMA.CONSTANTS; SELECT CONSTANT_SCHEMA, CONSTANT_NAME, DATA_TYPE, REMARKS, SQL FROM INFORMATION_SCHEMA.CONSTANTS;
> CONSTANT_CATALOG CONSTANT_SCHEMA CONSTANT_NAME DATA_TYPE REMARKS SQL > CONSTANT_SCHEMA CONSTANT_NAME DATA_TYPE REMARKS SQL
> ---------------- --------------- ------------- --------- ------- --- > --------------- ------------- --------- ------- ---
> SCRIPT PUBLIC ONE 4 1 > PUBLIC ONE 4 1
> rows: 1 > rows: 1
DROP CONSTANT ONE; DROP CONSTANT ONE;
...@@ -1713,18 +1713,18 @@ alter table test add constraint nu unique(parent); ...@@ -1713,18 +1713,18 @@ alter table test add constraint nu unique(parent);
alter table test add constraint fk foreign key(parent) references(id); alter table test add constraint fk foreign key(parent) references(id);
> ok > ok
select * from INFORMATION_SCHEMA.INDEXES; select TABLE_NAME, NON_UNIQUE, INDEX_NAME, ORDINAL_POSITION, COLUMN_NAME, CARDINALITY, PRIMARY_KEY from INFORMATION_SCHEMA.INDEXES;
> TABLE_CATALOG TABLE_SCHEMA TABLE_NAME NON_UNIQUE INDEX_NAME ORDINAL_POSITION COLUMN_NAME CARDINALITY PRIMARY_KEY INDEX_TYPE_NAME IS_GENERATED INDEX_TYPE ASC_OR_DESC PAGES FILTER_CONDITION REMARKS > TABLE_NAME NON_UNIQUE INDEX_NAME ORDINAL_POSITION COLUMN_NAME CARDINALITY PRIMARY_KEY
> ------------- ------------ ---------- ---------- ------------- ---------------- ----------- ----------- ----------- --------------- ------------ ---------- ----------- ----- ---------------- ------- > ---------- ---------- ------------- ---------------- ----------- ----------- -----------
> SCRIPT PUBLIC TEST FALSE NU_INDEX_0 1 PARENT 0 FALSE UNIQUE INDEX TRUE 3 A 0 > TEST FALSE NU_INDEX_0 1 PARENT 0 FALSE
> SCRIPT PUBLIC TEST FALSE PRIMARY_KEY_1 1 ID 0 TRUE PRIMARY KEY FALSE 3 A 0 > TEST FALSE PRIMARY_KEY_1 1 ID 0 TRUE
> SCRIPT PUBLIC TEST TRUE NI 1 PARENT 0 FALSE INDEX FALSE 3 A 0 > TEST TRUE NI 1 PARENT 0 FALSE
> rows: 3 > rows: 3
select * from INFORMATION_SCHEMA.SEQUENCES; select SEQUENCE_NAME, CURRENT_VALUE, INCREMENT, IS_GENERATED, REMARKS from INFORMATION_SCHEMA.SEQUENCES;
> SEQUENCE_CATALOG SEQUENCE_SCHEMA SEQUENCE_NAME CURRENT_VALUE INCREMENT IS_GENERATED REMARKS > SEQUENCE_NAME CURRENT_VALUE INCREMENT IS_GENERATED REMARKS
> ---------------- --------------- ------------- ------------- --------- ------------ ------- > ------------- ------------- --------- ------------ -------
> SCRIPT PUBLIC TEST_SEQ 0 1 FALSE > TEST_SEQ 0 1 FALSE
> rows: 1 > rows: 1
drop table test; drop table test;
...@@ -3575,10 +3575,10 @@ SCRIPT NOPASSWORDS NOSETTINGS; ...@@ -3575,10 +3575,10 @@ SCRIPT NOPASSWORDS NOSETTINGS;
> CREATE USER IF NOT EXISTS SA PASSWORD '' ADMIN > CREATE USER IF NOT EXISTS SA PASSWORD '' ADMIN
> rows: 2 > rows: 2
SELECT * FROM INFORMATION_SCHEMA.FUNCTION_ALIASES; SELECT ALIAS_NAME, JAVA_CLASS, JAVA_METHOD, DATA_TYPE, COLUMN_COUNT, RETURNS_RESULT, REMARKS FROM INFORMATION_SCHEMA.FUNCTION_ALIASES;
> ALIAS_CATALOG ALIAS_SCHEMA ALIAS_NAME JAVA_CLASS JAVA_METHOD DATA_TYPE COLUMN_COUNT RETURNS_RESULT REMARKS > ALIAS_NAME JAVA_CLASS JAVA_METHOD DATA_TYPE COLUMN_COUNT RETURNS_RESULT REMARKS
> ------------- ------------ ---------- -------------- ----------- --------- ------------ -------------- ------- > ---------- -------------- ----------- --------- ------------ -------------- -------
> SCRIPT PUBLIC MY_SQRT java.lang.Math sqrt 8 1 2 > MY_SQRT java.lang.Math sqrt 8 1 2
> rows: 1 > rows: 1
DROP ALIAS MY_SQRT; DROP ALIAS MY_SQRT;
...@@ -3592,10 +3592,10 @@ SELECT DISTINCT TABLE_SCHEMA, TABLE_CATALOG FROM INFORMATION_SCHEMA.TABLES ORDER ...@@ -3592,10 +3592,10 @@ SELECT DISTINCT TABLE_SCHEMA, TABLE_CATALOG FROM INFORMATION_SCHEMA.TABLES ORDER
> rows (ordered): 1 > rows (ordered): 1
SELECT * FROM INFORMATION_SCHEMA.SCHEMATA; SELECT * FROM INFORMATION_SCHEMA.SCHEMATA;
> CATALOG_NAME SCHEMA_NAME SCHEMA_OWNER DEFAULT_CHARACTER_SET_NAME DEFAULT_COLLATION_NAME IS_DEFAULT REMARKS > CATALOG_NAME SCHEMA_NAME SCHEMA_OWNER DEFAULT_CHARACTER_SET_NAME DEFAULT_COLLATION_NAME IS_DEFAULT REMARKS ID
> ------------ ------------------ ------------ -------------------------- ---------------------- ---------- ------- > ------------ ------------------ ------------ -------------------------- ---------------------- ---------- ------- --
> SCRIPT INFORMATION_SCHEMA SA Unicode OFF FALSE > SCRIPT INFORMATION_SCHEMA SA Unicode OFF FALSE -1
> SCRIPT PUBLIC SA Unicode OFF TRUE > SCRIPT PUBLIC SA Unicode OFF TRUE 0
> rows: 2 > rows: 2
SELECT * FROM INFORMATION_SCHEMA.CATALOGS; SELECT * FROM INFORMATION_SCHEMA.CATALOGS;
...@@ -3612,10 +3612,10 @@ SELECT INFORMATION_SCHEMA.SCHEMATA.SCHEMA_NAME FROM INFORMATION_SCHEMA.SCHEMATA; ...@@ -3612,10 +3612,10 @@ SELECT INFORMATION_SCHEMA.SCHEMATA.SCHEMA_NAME FROM INFORMATION_SCHEMA.SCHEMATA;
> rows: 2 > rows: 2
SELECT INFORMATION_SCHEMA.SCHEMATA.* FROM INFORMATION_SCHEMA.SCHEMATA; SELECT INFORMATION_SCHEMA.SCHEMATA.* FROM INFORMATION_SCHEMA.SCHEMATA;
> CATALOG_NAME SCHEMA_NAME SCHEMA_OWNER DEFAULT_CHARACTER_SET_NAME DEFAULT_COLLATION_NAME IS_DEFAULT REMARKS > CATALOG_NAME SCHEMA_NAME SCHEMA_OWNER DEFAULT_CHARACTER_SET_NAME DEFAULT_COLLATION_NAME IS_DEFAULT REMARKS ID
> ------------ ------------------ ------------ -------------------------- ---------------------- ---------- ------- > ------------ ------------------ ------------ -------------------------- ---------------------- ---------- ------- --
> SCRIPT INFORMATION_SCHEMA SA Unicode OFF FALSE > SCRIPT INFORMATION_SCHEMA SA Unicode OFF FALSE -1
> SCRIPT PUBLIC SA Unicode OFF TRUE > SCRIPT PUBLIC SA Unicode OFF TRUE 0
> rows: 2 > rows: 2
CREATE SCHEMA TEST_SCHEMA AUTHORIZATION SA; CREATE SCHEMA TEST_SCHEMA AUTHORIZATION SA;
...@@ -4037,14 +4037,14 @@ GRANT UPDATE ON TEST TO TEST_ROLE; ...@@ -4037,14 +4037,14 @@ GRANT UPDATE ON TEST TO TEST_ROLE;
GRANT TEST_ROLE TO TEST_USER; GRANT TEST_ROLE TO TEST_USER;
> ok > ok
SELECT * FROM INFORMATION_SCHEMA.ROLES; SELECT NAME FROM INFORMATION_SCHEMA.ROLES;
> NAME REMARKS > NAME
> --------- ------- > ---------
> PUBLIC > PUBLIC
> TEST_ROLE > TEST_ROLE
> rows: 2 > rows: 2
SELECT * FROM INFORMATION_SCHEMA.RIGHTS; SELECT GRANTEE, GRANTEETYPE, GRANTEDROLE, RIGHTS, TABLE_SCHEMA, TABLE_NAME FROM INFORMATION_SCHEMA.RIGHTS;
> GRANTEE GRANTEETYPE GRANTEDROLE RIGHTS TABLE_SCHEMA TABLE_NAME > GRANTEE GRANTEETYPE GRANTEDROLE RIGHTS TABLE_SCHEMA TABLE_NAME
> --------- ----------- ----------- -------------- ------------ ---------- > --------- ----------- ----------- -------------- ------------ ----------
> TEST_ROLE ROLE UPDATE PUBLIC TEST > TEST_ROLE ROLE UPDATE PUBLIC TEST
...@@ -4074,11 +4074,11 @@ REVOKE INSERT ON TEST FROM TEST_USER; ...@@ -4074,11 +4074,11 @@ REVOKE INSERT ON TEST FROM TEST_USER;
REVOKE TEST_ROLE FROM TEST_USER; REVOKE TEST_ROLE FROM TEST_USER;
> ok > ok
SELECT * FROM INFORMATION_SCHEMA.RIGHTS; SELECT GRANTEE, GRANTEETYPE, GRANTEDROLE, RIGHTS, TABLE_NAME FROM INFORMATION_SCHEMA.RIGHTS;
> GRANTEE GRANTEETYPE GRANTEDROLE RIGHTS TABLE_SCHEMA TABLE_NAME > GRANTEE GRANTEETYPE GRANTEDROLE RIGHTS TABLE_NAME
> --------- ----------- ----------- ------ ------------ ---------- > --------- ----------- ----------- ------ ----------
> TEST_ROLE ROLE UPDATE PUBLIC TEST > TEST_ROLE ROLE UPDATE TEST
> TEST_USER USER SELECT PUBLIC TEST > TEST_USER USER SELECT TEST
> rows: 2 > rows: 2
SELECT * FROM INFORMATION_SCHEMA.TABLE_PRIVILEGES; SELECT * FROM INFORMATION_SCHEMA.TABLE_PRIVILEGES;
...@@ -4098,14 +4098,14 @@ DROP ROLE TEST_ROLE; ...@@ -4098,14 +4098,14 @@ DROP ROLE TEST_ROLE;
> ok > ok
SELECT * FROM INFORMATION_SCHEMA.ROLES; SELECT * FROM INFORMATION_SCHEMA.ROLES;
> NAME REMARKS > NAME REMARKS ID
> ------ ------- > ------ ------- --
> PUBLIC > PUBLIC 0
> rows: 1 > rows: 1
SELECT * FROM INFORMATION_SCHEMA.RIGHTS; SELECT * FROM INFORMATION_SCHEMA.RIGHTS;
> GRANTEE GRANTEETYPE GRANTEDROLE RIGHTS TABLE_SCHEMA TABLE_NAME > GRANTEE GRANTEETYPE GRANTEDROLE RIGHTS TABLE_SCHEMA TABLE_NAME ID
> ------- ----------- ----------- ------ ------------ ---------- > ------- ----------- ----------- ------ ------------ ---------- --
> rows: 0 > rows: 0
--- plan ---------------------------------------------------------------------------------------------- --- plan ----------------------------------------------------------------------------------------------
...@@ -6162,10 +6162,10 @@ CALL IDENTITY(); ...@@ -6162,10 +6162,10 @@ CALL IDENTITY();
> 90123456789012345 > 90123456789012345
> rows: 1 > rows: 1
SELECT * FROM INFORMATION_SCHEMA.SEQUENCES; SELECT SEQUENCE_NAME, CURRENT_VALUE, INCREMENT FROM INFORMATION_SCHEMA.SEQUENCES;
> SEQUENCE_CATALOG SEQUENCE_SCHEMA SEQUENCE_NAME CURRENT_VALUE INCREMENT IS_GENERATED REMARKS > SEQUENCE_NAME CURRENT_VALUE INCREMENT
> ---------------- --------------- ------------- ----------------- --------- ------------ ------- > ------------- ----------------- ---------
> SCRIPT PUBLIC TEST_LONG 90123456789012345 -1 FALSE > TEST_LONG 90123456789012345 -1
> rows: 1 > rows: 1
SET AUTOCOMMIT TRUE; SET AUTOCOMMIT TRUE;
...@@ -6734,9 +6734,9 @@ SCRIPT NOPASSWORDS NOSETTINGS; ...@@ -6734,9 +6734,9 @@ SCRIPT NOPASSWORDS NOSETTINGS;
> CREATE USER IF NOT EXISTS TEST_ADMIN PASSWORD '' ADMIN > CREATE USER IF NOT EXISTS TEST_ADMIN PASSWORD '' ADMIN
> rows: 10 > rows: 10
SELECT * FROM INFORMATION_SCHEMA.USERS; SELECT NAME, ADMIN FROM INFORMATION_SCHEMA.USERS;
> NAME ADMIN REMARKS > NAME ADMIN
> ---------- ----- ------- > ---------- -----
> SA true > SA true
> TEST false > TEST false
> TEST2 false > TEST2 false
......
create table test as select 1 from dual union all select 2 from dual;
drop table test;
create table test_table(column_a integer); create table test_table(column_a integer);
insert into test_table values(1); insert into test_table values(1);
create view test_view AS SELECT * FROM (SELECT DISTINCT * FROM test_table) AS subquery; create view test_view AS SELECT * FROM (SELECT DISTINCT * FROM test_table) AS subquery;
......
...@@ -134,6 +134,7 @@ public class TestScriptReader extends TestBase { ...@@ -134,6 +134,7 @@ public class TestScriptReader extends TestBase {
check(source.readStatement(),"/*;\n*/"); check(source.readStatement(),"/*;\n*/");
check(source.readStatement(),"//;\na"); check(source.readStatement(),"//;\na");
check(source.readStatement(), null); check(source.readStatement(), null);
source.close();
} }
} }
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论