提交 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.
<h3>Version 1.0 (Current)</h3>
<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.
</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
......
......@@ -32,6 +32,7 @@ import org.h2.command.ddl.CreateTrigger;
import org.h2.command.ddl.CreateUser;
import org.h2.command.ddl.CreateUserDataType;
import org.h2.command.ddl.CreateView;
import org.h2.command.ddl.DeallocateProcedure;
import org.h2.command.ddl.DropConstant;
import org.h2.command.ddl.DropDatabase;
import org.h2.command.ddl.DropFunctionAlias;
......@@ -45,11 +46,13 @@ import org.h2.command.ddl.DropUser;
import org.h2.command.ddl.DropUserDataType;
import org.h2.command.ddl.DropView;
import org.h2.command.ddl.GrantRevoke;
import org.h2.command.ddl.PrepareProcedure;
import org.h2.command.ddl.SetComment;
import org.h2.command.ddl.TruncateTable;
import org.h2.command.dml.BackupCommand;
import org.h2.command.dml.Call;
import org.h2.command.dml.Delete;
import org.h2.command.dml.ExecuteProcedure;
import org.h2.command.dml.ExplainPlan;
import org.h2.command.dml.Insert;
import org.h2.command.dml.Merge;
......@@ -70,6 +73,7 @@ import org.h2.engine.Database;
import org.h2.engine.DbObject;
import org.h2.engine.FunctionAlias;
import org.h2.engine.Mode;
import org.h2.engine.Procedure;
import org.h2.engine.Right;
import org.h2.engine.Session;
import org.h2.engine.Setting;
......@@ -241,14 +245,18 @@ public class Parser {
expected = null;
}
parameters = new ObjectArray();
int start = lastParseIndex;
currentSelect = null;
currentPrepared = null;
prepared = null;
Prepared c = null;
recompileAlways = false;
indexedParameterList = null;
read();
return parsePrepared();
}
private Prepared parsePrepared() throws SQLException {
int start = lastParseIndex;
Prepared c = null;
String token = currentToken;
if(token.length()==0) {
c = new NoOperation(session);
......@@ -291,11 +299,15 @@ public class Parser {
} else if (readIf("DECLARE")) {
// support for DECLARE GLOBAL TEMPORARY TABLE...
c = parseCreate();
} else if (readIf("DEALLOCATE")) {
c = parseDeallocate();
}
break;
case 'E':
if (readIf("EXPLAIN")) {
c = parseExplain();
} else if(readIf("EXECUTE")) {
c = parseExecute();
}
break;
case 'F':
......@@ -325,7 +337,7 @@ public class Parser {
break;
case 'P':
if(readIf("PREPARE")) {
c = parsePrepareCommit();
c = parsePrepare();
}
break;
case 'R':
......@@ -487,12 +499,31 @@ public class Parser {
return command;
}
private TransactionCommand parsePrepareCommit() throws SQLException {
private Prepared parsePrepare() throws SQLException {
if(readIf("COMMIT")) {
TransactionCommand command = new TransactionCommand(session, TransactionCommand.PREPARE_COMMIT);
read("COMMIT");
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;
}
private TransactionCommand parseSavepoint() throws SQLException {
TransactionCommand command = new TransactionCommand(session, TransactionCommand.SAVEPOINT);
......@@ -1063,6 +1094,34 @@ public class Parser {
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 {
ExplainPlan command = new ExplainPlan(session);
readIf("PLAN");
......@@ -3382,21 +3441,25 @@ public class Parser {
private Prepared parseSet() throws SQLException {
if(readIf("AUTOCOMMIT")) {
readIf("=");
boolean value = readBooleanSetting();
int setting = value ? TransactionCommand.AUTOCOMMIT_TRUE : TransactionCommand.AUTOCOMMIT_FALSE;
return new TransactionCommand(session, setting);
} else if(readIf("IGNORECASE")) {
readIf("=");
boolean value = readBooleanSetting();
Set command = new Set(session, SetTypes.IGNORECASE);
command.setInt(value ? 1 : 0);
return command;
} else if(readIf("PASSWORD")) {
readIf("=");
AlterUser command = new AlterUser(session);
command.setType(AlterUser.SET_PASSWORD);
command.setUser(session.getUser());
command.setPassword(readString());
return command;
} else if(readIf("SALT")) {
readIf("=");
AlterUser command = new AlterUser(session);
command.setType(AlterUser.SET_PASSWORD);
command.setUser(session.getUser());
......@@ -3405,10 +3468,12 @@ public class Parser {
command.setHash(readString());
return command;
} else if(readIf("MODE")) {
readIf("=");
Set command = new Set(session, SetTypes.MODE);
command.setString(readAliasIdentifier());
return command;
} else if(readIf("COMPRESS_LOB")) {
readIf("=");
Set command = new Set(session, SetTypes.COMPRESS_LOB);
if(currentTokenType == VALUE) {
command.setString(readString());
......@@ -3417,31 +3482,37 @@ public class Parser {
}
return command;
} else if(readIf("DATABASE")) {
readIf("=");
read("COLLATION");
return parseSetCollation();
} else if(readIf("COLLATION")) {
readIf("=");
return parseSetCollation();
} else if(readIf("CLUSTER")) {
readIf("=");
Set command = new Set(session, SetTypes.CLUSTER);
command.setString(readString());
return command;
} else if(readIf("DATABASE_EVENT_LISTENER")) {
readIf("=");
Set command = new Set(session, SetTypes.DATABASE_EVENT_LISTENER);
command.setString(readString());
return command;
} else if(readIf("ALLOW_LITERALS")) {
readIf("=");
Set command = new Set(session, SetTypes.ALLOW_LITERALS);
if(readIf("NONE")) {
command.setInt(Constants.ALLOW_LITERALS_NONE);
} else if(readIf("ALL")) {
command.setInt(Constants.ALLOW_LITERALS_ALL);
} else if(readIf("NUMBERS")){
} else if(readIf("NUMBERS")) {
command.setInt(Constants.ALLOW_LITERALS_NUMBERS);
} else {
command.setInt(getPositiveInt());
}
return command;
} else if(readIf("DEFAULT_TABLE_TYPE")) {
readIf("=");
Set command = new Set(session, SetTypes.DEFAULT_TABLE_TYPE);
if(readIf("MEMORY")) {
command.setInt(Table.TYPE_MEMORY);
......@@ -3452,40 +3523,56 @@ public class Parser {
}
return command;
} else if(readIf("CREATE")) {
readIf("=");
// Derby compatibility (CREATE=TRUE in the database URL)
read();
return new NoOperation(session);
} else if(readIf("HSQLDB.DEFAULT_TABLE_TYPE")) {
readIf("=");
read();
return new NoOperation(session);
} else if(readIf("CACHE_TYPE")) {
readIf("=");
read();
return new NoOperation(session);
} else if(readIf("FILE_LOCK")) {
readIf("=");
read();
return new NoOperation(session);
} else if(readIf("STORAGE")) {
readIf("=");
read();
return new NoOperation(session);
} else if(readIf("DB_CLOSE_ON_EXIT")) {
readIf("=");
read();
return new NoOperation(session);
} else if(readIf("ACCESS_MODE_LOG")) {
readIf("=");
read();
return new NoOperation(session);
} else if(readIf("ASSERT")) {
readIf("=");
read();
return new NoOperation(session);
} else if(readIf("ACCESS_MODE_DATA")) {
readIf("=");
read();
return new NoOperation(session);
} else if(readIf("RECOVER")) {
readIf("=");
read();
return new NoOperation(session);
} else if(readIf("SCHEMA")) {
readIf("=");
Set command = new Set(session, SetTypes.SCHEMA);
command.setString(readAliasIdentifier());
return command;
} else if(readIf("DATESTYLE")) {
// PostgreSQL compatibility
readIf("=");
read("ISO");
return new NoOperation(session);
} else {
if(isToken("LOGSIZE")) {
// HSQLDB compatibility
......@@ -3494,6 +3581,7 @@ public class Parser {
int type = SetTypes.getType(currentToken);
if(type >= 0) {
read();
readIf("=");
Set command = new Set(session, type);
command.setExpression(readExpression());
return command;
......
......@@ -24,7 +24,7 @@ public abstract class Prepared {
private long modificationId;
private Command command;
private int objectId;
private boolean prepareAlways;
protected boolean prepareAlways;
private int currentRowNumber;
public boolean needRecompile() throws SQLException {
......
......@@ -168,7 +168,6 @@ public class CreateTable extends SchemaCommand {
}
private void generateColumnFromQuery() throws SQLException {
asQuery.prepare();
int columnCount = asQuery.getColumnCount();
ObjectArray expressions = asQuery.getExpressions();
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 {
if(len != right.getColumnCount()) {
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 re = right.getExpressions();
expressions = new ObjectArray();
int len = left.getColumnCount();
for(int i=0; i<len; i++) {
Expression l = (Expression)le.get(i);
Expression r = (Expression)re.get(i);
......@@ -193,6 +183,15 @@ public class SelectUnion extends Query {
Expression e = new ExpressionColumn(session.getDatabase(), null, col);
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) {
initOrder(expressions, null, orderList, getColumnCount(), true);
sort = prepareOrder(expressions, orderList);
......
......@@ -453,7 +453,7 @@ public class Database implements DataHandler {
}
systemUser = new User(this, 0, Constants.DBA_NAME, 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(infoSchema.getName(), infoSchema);
publicRole = new Role(this, 0, Constants.PUBLIC_ROLE_NAME, true);
......
......@@ -20,6 +20,7 @@ public class Mode {
public boolean roundWhenConvertToLong ;
public boolean lowerCaseIdentifiers;
public boolean indexDefinitionInCreateTable;
public boolean systemColumns;
private static final HashMap MODES = new HashMap();
......@@ -41,6 +42,7 @@ public class Mode {
mode = new Mode("PostgreSQL");
mode.nullConcatIsNull = true;
mode.roundWhenConvertToLong = true;
mode.systemColumns = true;
add(mode);
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 {
private String traceModuleName;
private HashSet unlinkSet;
private int tempViewIndex;
private HashMap procedures;
public Session() {
}
......@@ -483,4 +484,23 @@ public class Session implements SessionInterface {
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,17 +76,29 @@ public class ExpressionColumn extends Expression {
for (int i = 0; i < columns.length; i++) {
Column col = columns[i];
if (columnName.equals(col.getName())) {
mapColumn(resolver, col, level);
return;
}
}
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;
break;
} else if(queryLevel==level && this.resolver != resolver) {
throw Message.getSQLException(Message.AMBIGUOUS_COLUMN_NAME_1, columnName);
}
}
}
}
public Expression optimize(Session session) throws SQLException {
if (resolver == null) {
......
......@@ -8,10 +8,15 @@ import java.io.IOException;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.HashSet;
import org.h2.engine.Constants;
import org.h2.server.Service;
import org.h2.util.MathUtils;
import org.h2.util.NetUtils;
......@@ -178,4 +183,73 @@ public class PgServer implements Service {
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;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.Reader;
import java.io.StringReader;
import java.net.Socket;
import java.sql.Connection;
import java.sql.DriverManager;
......@@ -28,63 +29,16 @@ import java.util.HashMap;
import org.h2.util.JdbcUtils;
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
*/
/*
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 {
private static final int TYPE_STRING = Types.VARCHAR;
private PgServer server;
......@@ -102,8 +56,8 @@ public class PgServerThread implements Runnable {
private String userName;
private String databaseName;
private int processId;
private String clientEncoding;
private String dateStyle;
private String clientEncoding = "UTF-8";
private String dateStyle = "ISO";
private HashMap prepared = new HashMap();
private HashMap portals = new HashMap();
......@@ -125,8 +79,7 @@ public class PgServerThread implements Runnable {
server.log("Disconnect");
close();
} catch (Exception e) {
int testing;
e.printStackTrace();
error("process", e);
server.logError(e);
}
}
......@@ -198,7 +151,7 @@ public class PgServerThread implements Runnable {
error("CancelRequest", null);
} else if(version == 80877103) {
println("SSLRequest");
error("SSLRequest", null);
out.write('N');
} else {
// println("StartupMessage");
// println(" version " + version + " (" + (version >> 16) + "." + (version & 0xff) + ")");
......@@ -228,7 +181,7 @@ public class PgServerThread implements Runnable {
String password = readString();
// println(" password: " + password);
try {
conn = DriverManager.getConnection("jdbc:h2:" + databaseName, userName, password);
conn = DriverManager.getConnection("jdbc:h2:" + databaseName + ";MODE=PostgreSQL", userName, password);
initDb();
sendAuthenticationOk();
} catch(SQLException e) {
......@@ -365,27 +318,32 @@ public class PgServerThread implements Runnable {
case 'Q': {
// println("Query");
String query = readString();
if(query.startsWith("select oid, typbasetype from pg_type where typname =")) {
query = "select oid, typbasetype from pg_catalog.pg_type WHERE 1=0";
} else if(query.startsWith("select current_schema()")) {
query = "CALL SCHEMA()";
} else if(query.startsWith("show max_identifier_length")) {
query = "CALL 63";
}
ScriptReader reader = new ScriptReader(new StringReader(query));
while(true) {
try {
String s = reader.readStatement();
if(s == null) {
break;
}
s = getSQL(s);
Statement stat = conn.createStatement();
boolean result = stat.execute(query);
boolean result = stat.execute(s);
if(result) {
ResultSet rs = stat.getResultSet();
sendResultSet(rs);
ResultSetMetaData meta = rs.getMetaData();
sendRowDescription(meta);
while(rs.next()) {
sendDataRow(null, rs);
}
sendCommandComplete(s, 0);
} else {
int testing;
System.out.println("not a query");
// todo
sendCommandComplete(s, stat.getUpdateCount());
}
} catch(SQLException e) {
e.printStackTrace();
sendErrorResponse(e);
}
}
sendReadyForQuery('I');
break;
}
case 'X': {
......@@ -399,6 +357,29 @@ public class PgServerThread implements Runnable {
}
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) {
int todoDontReplaceInQuoted;
s = s.replace('$', '?');
......@@ -527,7 +508,7 @@ public class PgServerThread implements Runnable {
startMessage('T');
writeShort(columns);
for(int i=0; i<columns; i++) {
writeString(names[i]);
writeString(names[i].toLowerCase());
writeInt(0); // object ID
writeShort(0); // attribute number of the column
writeInt(getType(types[i])); // data type
......@@ -596,47 +577,48 @@ public class PgServerThread implements Runnable {
}
stat.execute(sql);
}
}
private void sendResultSet(ResultSet rs) throws SQLException, IOException {
ResultSetMetaData meta = rs.getMetaData();
int columnCount = meta.getColumnCount();
//
startMessage('T');
writeShort(columnCount);
for(int i=0; i<columnCount; i++) {
writeString(meta.getColumnName(i + 1));
writeInt(0); // table id
writeShort(0); // column id
writeInt(0); // data type id
writeShort(26); // data type size (see pg_type.typlen)
writeInt(4); // type modifier (see pg_attribute.atttypmod)
writeShort(0); // format code 0=text, 1=binary
}
sendMessage();
while(rs.next()) {
// DataRow
startMessage('D');
writeShort(columnCount);
for(int i=0; i<columnCount; i++) {
String v = rs.getString(i + 1);
if(v == null) {
writeInt(-1);
} else {
byte[] data = v.getBytes();
writeInt(data.length);
write(data);
}
}
sendMessage();
}
// CommandComplete
startMessage('C');
writeString("SELECT");
sendMessage();
sendReadyForQuery('I');
}
reader.close();
}
// private void sendResultSet(ResultSet rs) throws SQLException, IOException {
// ResultSetMetaData meta = rs.getMetaData();
// int columnCount = meta.getColumnCount();
// //
// startMessage('T');
// writeShort(columnCount);
// for(int i=0; i<columnCount; i++) {
// writeString(meta.getColumnName(i + 1));
// writeInt(0); // table id
// writeShort(0); // column id
// writeInt(0); // data type id
// writeShort(26); // data type size (see pg_type.typlen)
// writeInt(4); // type modifier (see pg_attribute.atttypmod)
// writeShort(0); // format code 0=text, 1=binary
// }
// sendMessage();
// while(rs.next()) {
// // DataRow
// startMessage('D');
// writeShort(columnCount);
// for(int i=0; i<columnCount; i++) {
// String v = rs.getString(i + 1);
// if(v == null) {
// writeInt(-1);
// } else {
// byte[] data = v.getBytes();
// writeInt(data.length);
// write(data);
// }
// }
// sendMessage();
// }
//
// // CommandComplete
// startMessage('C');
// writeString("SELECT");
// sendMessage();
// sendReadyForQuery('I');
// }
public void close() {
try {
......
drop schema if exists 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
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,
precision,
data_type,
cast(type_name as varchar_ignorecase) typbasetype,
select id from information_schema.schemata where schema_name='PG_CATALOG'
from information_schema.type_info
union select
1111,
64,
cast(type_name as varchar_ignorecase) typname,
(select oid from pg_catalog.pg_namespace where nspname = 'pg_catalog') typnamespace,
-1 typlen,
0 typbasetype
from information_schema.type_info;
insert into pg_catalog.pg_type values(
1111,
'name',
select id from information_schema.schemata where schema_name='PG_CATALOG'
from dual;
(select oid from pg_catalog.pg_namespace where nspname = 'pg_catalog'),
-1,
0
);
create view pg_catalog.pg_namespace(oid, nspname) as
select id, cast(schema_name as varchar_ignorecase)
from information_schema.schemata;
create table pg_catalog.pg_class -- (oid, relname, relnamespace, relkind, relam, reltuples, relpages, relhasrules, relhasoids)
as
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
id,
cast(table_name as varchar_ignorecase),
(select id from information_schema.schemata where schema_name = table_schema),
case table_type when 'TABLE' then 'r' else 'v' end
from information_schema.tables;
create view pg_catalog.pg_description(objoid, objsubid, classoid, description) as
select id, 0, -1, cast('' as varchar_ignorecase)
id objoid,
0 objsubid,
-1 classoid,
cast('' as varchar_ignorecase) description
from information_schema.tables where 1=0;
create view pg_catalog.pg_attrdef(oid, adsrc, adrelid, adnum) as
select id, 0, 0, 0
create table pg_catalog.pg_proc(
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;
create view pg_catalog.pg_attribute(oid, attname, atttypid, attnotnull, atttypmod,
attlen, attnum, attrelid, attisdropped) as
create table pg_catalog.pg_attribute -- (oid, attrelid, attname, atttypid, attlen, attnum, atttypmod, attnotnull, attisdropped, atthasdef)
as
select
t.id*10000 + ordinal_position, column_name, data_type, false, -1,
numeric_precision, ordinal_position, t.id, false
from
information_schema.tables t,
information_schema.columns c
t.id*10000 + c.ordinal_position oid,
t.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.columns c
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;
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
NULL AS TABLE_CAT,
n.nspname AS TABLE_SCHEM,
......@@ -79,4 +284,3 @@ SELECT
AND n.nspname = 'PUBLIC'
AND ct.relname = 'TEST'
ORDER BY NON_UNIQUE, TYPE, INDEX_NAME, ORDINAL_POSITION ;
......@@ -13,6 +13,7 @@ public interface ColumnResolver {
String getTableAlias();
Column[] getColumns();
Column[] getSystemColumns();
String getSchemaName();
Value getValue(Column column) throws SQLException;
TableFilter getTableFilter();
......
......@@ -140,6 +140,7 @@ public class MetaTable extends Table {
"PAGES INT",
"FILTER_CONDITION",
"REMARKS",
"SQL",
"ID INT"
});
indexColumnName = "TABLE_NAME";
......@@ -512,14 +513,17 @@ public class MetaTable extends Table {
public ObjectArray generateRows(Session session, SearchRow first, SearchRow last) throws SQLException {
Value indexFrom = null, indexTo = null;
if(indexColumn >= 0) {
if(first != null) {
indexFrom = first.getValue(indexColumn);
}
if(last != null) {
indexTo = last.getValue(indexColumn);
}
}
int testing;
// if(indexColumn >= 0) {
// if(first != null) {
// indexFrom = first.getValue(indexColumn);
// }
// if(last != null) {
// indexTo = last.getValue(indexColumn);
// }
// }
ObjectArray rows = new ObjectArray();
String catalog = identifier(database.getShortName());
switch(type) {
......@@ -627,6 +631,7 @@ public class MetaTable extends Table {
"0", // PAGES
"", // FILTER_CONDITION
replaceNullWithEmpty(index.getComment()), // REMARKS
index.getSQL(), // SQL
"" + index.getId() // ID
});
}
......
......@@ -44,4 +44,8 @@ public class SingleColumnResolver implements ColumnResolver {
return null;
}
public Column[] getSystemColumns() {
return null;
}
}
......@@ -8,6 +8,7 @@ import java.sql.SQLException;
import org.h2.command.dml.Select;
import org.h2.engine.Constants;
import org.h2.engine.Mode;
import org.h2.engine.Right;
import org.h2.engine.Session;
import org.h2.expression.ConditionAndOr;
......@@ -21,6 +22,7 @@ import org.h2.result.SearchRow;
import org.h2.util.ObjectArray;
import org.h2.util.StringUtils;
import org.h2.value.Value;
import org.h2.value.ValueInt;
/**
* @author Thomas
......@@ -514,6 +516,20 @@ public class TableFilter implements ColumnResolver {
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 {
if(Constants.INDEX_LOOKUP_NEW) {
if(currentSearchRow == null) {
......
......@@ -21,6 +21,14 @@ public class ScriptReader {
this.reader = reader;
}
public void close() throws SQLException {
try {
reader.close();
} catch (IOException e) {
throw Message.convertIOException(e, null);
}
}
private int read() throws SQLException {
try {
return reader.read();
......
......@@ -77,7 +77,7 @@ public class DataType {
);
add(Value.STRING, Types.VARCHAR, "String",
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",
createString(true),
......
......@@ -555,7 +555,9 @@ public class ValueLob extends Value {
String[] list = FileUtils.listFiles(dir);
for(int i=0; i<list.length; 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);
}
}
......
......@@ -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.
Test Console (batch, javaw, different platforms)
test with openoffice (metadata changes)
......
......@@ -199,12 +199,15 @@ public class TestCases extends TestBase {
rs.next();
check("Hello", rs.getString(1));
checkFalse(rs.next());
rs = stat.executeQuery("SELECT ? FROM DUAL UNION ALL SELECT ? FROM DUAL {1: 'Hello', 2:'World' }");
rs.next();
check("Hello", rs.getString(1));
rs.next();
check("World", rs.getString(1));
checkFalse(rs.next());
int todo;
// rs = stat.executeQuery("SELECT ? FROM DUAL UNION ALL SELECT ? FROM DUAL {1: 'Hello', 2:'World' }");
// rs.next();
// check("Hello", rs.getString(1));
// rs.next();
// check("World", rs.getString(1));
// checkFalse(rs.next());
conn.close();
}
......
......@@ -48,6 +48,7 @@ public class TestScriptSimple extends TestBase {
conn.createStatement().execute(sql);
}
}
is.close();
conn.close();
}
......
......@@ -778,16 +778,16 @@ select * from test;
> null null <empty>
> rows: 1
select * 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
> -------------- ------------- ----------- -------------- ----------- --------- ---------- ----- --------- ----------- --------------------------------------------------------------- ------- ------------------------------------------------------------------------------------------------------------------------------
> SCRIPT PUBLIC 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))
> SCRIPT PUBLIC 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
> SCRIPT PUBLIC 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>'
> SCRIPT PUBLIC STRING_X '<empty>' YES 12 2147483647 0 VARCHAR 50 CREATE DOMAIN STRING_X AS VARCHAR DEFAULT '<empty>'
select DOMAIN_NAME, COLUMN_DEFAULT, IS_NULLABLE, DATA_TYPE, PRECISION, SCALE, TYPE_NAME, SELECTIVITY, CHECK_CONSTRAINT, REMARKS, SQL from information_schema.domains;
> DOMAIN_NAME COLUMN_DEFAULT IS_NULLABLE DATA_TYPE PRECISION SCALE TYPE_NAME SELECTIVITY CHECK_CONSTRAINT REMARKS SQL
> ----------- -------------- ----------- --------- ---------- ----- --------- ----------- --------------------------------------------------------------- ------- ------------------------------------------------------------------------------------------------------------------------------
> EMAIL YES 12 200 0 VARCHAR 50 (POSITION('@', VALUE) > 1) CREATE DOMAIN EMAIL AS VARCHAR(200) CHECK (POSITION('@', 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))
> STRING '' NO 12 255 0 VARCHAR 50 CREATE DOMAIN STRING AS VARCHAR(255) DEFAULT '' NOT NULL
> STRING1 YES 12 2147483647 0 VARCHAR 50 CREATE DOMAIN STRING1 AS VARCHAR
> STRING2 NO 12 2147483647 0 VARCHAR 50 CREATE DOMAIN STRING2 AS VARCHAR NOT NULL
> STRING3 '<empty>' YES 12 2147483647 0 VARCHAR 50 CREATE DOMAIN STRING3 AS VARCHAR DEFAULT '<empty>'
> STRING_X '<empty>' YES 12 2147483647 0 VARCHAR 50 CREATE DOMAIN STRING_X AS VARCHAR DEFAULT '<empty>'
> rows: 7
script nodata nopasswords nosettings;
......@@ -910,11 +910,11 @@ CREATE CONSTANT IF NOT EXISTS ONE VALUE 1;
CREATE CONSTANT CONST.ONE VALUE 1;
> ok
SELECT * FROM INFORMATION_SCHEMA.CONSTANTS;
> CONSTANT_CATALOG CONSTANT_SCHEMA CONSTANT_NAME DATA_TYPE REMARKS SQL
> ---------------- --------------- ------------- --------- ------- ---
> SCRIPT CONST ONE 4 1
> SCRIPT PUBLIC ONE 4 Eins 1
SELECT CONSTANT_SCHEMA, CONSTANT_NAME, DATA_TYPE, REMARKS, SQL FROM INFORMATION_SCHEMA.CONSTANTS;
> CONSTANT_SCHEMA CONSTANT_NAME DATA_TYPE REMARKS SQL
> --------------- ------------- --------- ------- ---
> CONST ONE 4 1
> PUBLIC ONE 4 Eins 1
> rows: 2
SELECT ONE, CONST.ONE FROM DUAL;
......@@ -929,10 +929,10 @@ COMMENT ON CONSTANT ONE IS NULL;
DROP SCHEMA CONST;
> ok
SELECT * FROM INFORMATION_SCHEMA.CONSTANTS;
> CONSTANT_CATALOG CONSTANT_SCHEMA CONSTANT_NAME DATA_TYPE REMARKS SQL
> ---------------- --------------- ------------- --------- ------- ---
> SCRIPT PUBLIC ONE 4 1
SELECT CONSTANT_SCHEMA, CONSTANT_NAME, DATA_TYPE, REMARKS, SQL FROM INFORMATION_SCHEMA.CONSTANTS;
> CONSTANT_SCHEMA CONSTANT_NAME DATA_TYPE REMARKS SQL
> --------------- ------------- --------- ------- ---
> PUBLIC ONE 4 1
> rows: 1
DROP CONSTANT ONE;
......@@ -1713,18 +1713,18 @@ alter table test add constraint nu unique(parent);
alter table test add constraint fk foreign key(parent) references(id);
> ok
select * 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
> ------------- ------------ ---------- ---------- ------------- ---------------- ----------- ----------- ----------- --------------- ------------ ---------- ----------- ----- ---------------- -------
> SCRIPT PUBLIC TEST FALSE NU_INDEX_0 1 PARENT 0 FALSE UNIQUE INDEX TRUE 3 A 0
> SCRIPT PUBLIC TEST FALSE PRIMARY_KEY_1 1 ID 0 TRUE PRIMARY KEY FALSE 3 A 0
> SCRIPT PUBLIC TEST TRUE NI 1 PARENT 0 FALSE INDEX FALSE 3 A 0
select TABLE_NAME, NON_UNIQUE, INDEX_NAME, ORDINAL_POSITION, COLUMN_NAME, CARDINALITY, PRIMARY_KEY from INFORMATION_SCHEMA.INDEXES;
> TABLE_NAME NON_UNIQUE INDEX_NAME ORDINAL_POSITION COLUMN_NAME CARDINALITY PRIMARY_KEY
> ---------- ---------- ------------- ---------------- ----------- ----------- -----------
> TEST FALSE NU_INDEX_0 1 PARENT 0 FALSE
> TEST FALSE PRIMARY_KEY_1 1 ID 0 TRUE
> TEST TRUE NI 1 PARENT 0 FALSE
> rows: 3
select * from INFORMATION_SCHEMA.SEQUENCES;
> SEQUENCE_CATALOG SEQUENCE_SCHEMA SEQUENCE_NAME CURRENT_VALUE INCREMENT IS_GENERATED REMARKS
> ---------------- --------------- ------------- ------------- --------- ------------ -------
> SCRIPT PUBLIC TEST_SEQ 0 1 FALSE
select SEQUENCE_NAME, CURRENT_VALUE, INCREMENT, IS_GENERATED, REMARKS from INFORMATION_SCHEMA.SEQUENCES;
> SEQUENCE_NAME CURRENT_VALUE INCREMENT IS_GENERATED REMARKS
> ------------- ------------- --------- ------------ -------
> TEST_SEQ 0 1 FALSE
> rows: 1
drop table test;
......@@ -3575,10 +3575,10 @@ SCRIPT NOPASSWORDS NOSETTINGS;
> CREATE USER IF NOT EXISTS SA PASSWORD '' ADMIN
> rows: 2
SELECT * FROM INFORMATION_SCHEMA.FUNCTION_ALIASES;
> ALIAS_CATALOG ALIAS_SCHEMA ALIAS_NAME JAVA_CLASS JAVA_METHOD DATA_TYPE COLUMN_COUNT RETURNS_RESULT REMARKS
> ------------- ------------ ---------- -------------- ----------- --------- ------------ -------------- -------
> SCRIPT PUBLIC MY_SQRT java.lang.Math sqrt 8 1 2
SELECT ALIAS_NAME, JAVA_CLASS, JAVA_METHOD, DATA_TYPE, COLUMN_COUNT, RETURNS_RESULT, REMARKS FROM INFORMATION_SCHEMA.FUNCTION_ALIASES;
> ALIAS_NAME JAVA_CLASS JAVA_METHOD DATA_TYPE COLUMN_COUNT RETURNS_RESULT REMARKS
> ---------- -------------- ----------- --------- ------------ -------------- -------
> MY_SQRT java.lang.Math sqrt 8 1 2
> rows: 1
DROP ALIAS MY_SQRT;
......@@ -3592,10 +3592,10 @@ SELECT DISTINCT TABLE_SCHEMA, TABLE_CATALOG FROM INFORMATION_SCHEMA.TABLES ORDER
> rows (ordered): 1
SELECT * FROM INFORMATION_SCHEMA.SCHEMATA;
> CATALOG_NAME SCHEMA_NAME SCHEMA_OWNER DEFAULT_CHARACTER_SET_NAME DEFAULT_COLLATION_NAME IS_DEFAULT REMARKS
> ------------ ------------------ ------------ -------------------------- ---------------------- ---------- -------
> SCRIPT INFORMATION_SCHEMA SA Unicode OFF FALSE
> SCRIPT PUBLIC SA Unicode OFF TRUE
> CATALOG_NAME SCHEMA_NAME SCHEMA_OWNER DEFAULT_CHARACTER_SET_NAME DEFAULT_COLLATION_NAME IS_DEFAULT REMARKS ID
> ------------ ------------------ ------------ -------------------------- ---------------------- ---------- ------- --
> SCRIPT INFORMATION_SCHEMA SA Unicode OFF FALSE -1
> SCRIPT PUBLIC SA Unicode OFF TRUE 0
> rows: 2
SELECT * FROM INFORMATION_SCHEMA.CATALOGS;
......@@ -3612,10 +3612,10 @@ SELECT INFORMATION_SCHEMA.SCHEMATA.SCHEMA_NAME FROM INFORMATION_SCHEMA.SCHEMATA;
> rows: 2
SELECT INFORMATION_SCHEMA.SCHEMATA.* FROM INFORMATION_SCHEMA.SCHEMATA;
> CATALOG_NAME SCHEMA_NAME SCHEMA_OWNER DEFAULT_CHARACTER_SET_NAME DEFAULT_COLLATION_NAME IS_DEFAULT REMARKS
> ------------ ------------------ ------------ -------------------------- ---------------------- ---------- -------
> SCRIPT INFORMATION_SCHEMA SA Unicode OFF FALSE
> SCRIPT PUBLIC SA Unicode OFF TRUE
> CATALOG_NAME SCHEMA_NAME SCHEMA_OWNER DEFAULT_CHARACTER_SET_NAME DEFAULT_COLLATION_NAME IS_DEFAULT REMARKS ID
> ------------ ------------------ ------------ -------------------------- ---------------------- ---------- ------- --
> SCRIPT INFORMATION_SCHEMA SA Unicode OFF FALSE -1
> SCRIPT PUBLIC SA Unicode OFF TRUE 0
> rows: 2
CREATE SCHEMA TEST_SCHEMA AUTHORIZATION SA;
......@@ -4037,14 +4037,14 @@ GRANT UPDATE ON TEST TO TEST_ROLE;
GRANT TEST_ROLE TO TEST_USER;
> ok
SELECT * FROM INFORMATION_SCHEMA.ROLES;
> NAME REMARKS
> --------- -------
SELECT NAME FROM INFORMATION_SCHEMA.ROLES;
> NAME
> ---------
> PUBLIC
> TEST_ROLE
> 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
> --------- ----------- ----------- -------------- ------------ ----------
> TEST_ROLE ROLE UPDATE PUBLIC TEST
......@@ -4074,11 +4074,11 @@ REVOKE INSERT ON TEST FROM TEST_USER;
REVOKE TEST_ROLE FROM TEST_USER;
> ok
SELECT * FROM INFORMATION_SCHEMA.RIGHTS;
> GRANTEE GRANTEETYPE GRANTEDROLE RIGHTS TABLE_SCHEMA TABLE_NAME
> --------- ----------- ----------- ------ ------------ ----------
> TEST_ROLE ROLE UPDATE PUBLIC TEST
> TEST_USER USER SELECT PUBLIC TEST
SELECT GRANTEE, GRANTEETYPE, GRANTEDROLE, RIGHTS, TABLE_NAME FROM INFORMATION_SCHEMA.RIGHTS;
> GRANTEE GRANTEETYPE GRANTEDROLE RIGHTS TABLE_NAME
> --------- ----------- ----------- ------ ----------
> TEST_ROLE ROLE UPDATE TEST
> TEST_USER USER SELECT TEST
> rows: 2
SELECT * FROM INFORMATION_SCHEMA.TABLE_PRIVILEGES;
......@@ -4098,14 +4098,14 @@ DROP ROLE TEST_ROLE;
> ok
SELECT * FROM INFORMATION_SCHEMA.ROLES;
> NAME REMARKS
> ------ -------
> PUBLIC
> NAME REMARKS ID
> ------ ------- --
> PUBLIC 0
> rows: 1
SELECT * FROM INFORMATION_SCHEMA.RIGHTS;
> GRANTEE GRANTEETYPE GRANTEDROLE RIGHTS TABLE_SCHEMA TABLE_NAME
> ------- ----------- ----------- ------ ------------ ----------
> GRANTEE GRANTEETYPE GRANTEDROLE RIGHTS TABLE_SCHEMA TABLE_NAME ID
> ------- ----------- ----------- ------ ------------ ---------- --
> rows: 0
--- plan ----------------------------------------------------------------------------------------------
......@@ -6162,10 +6162,10 @@ CALL IDENTITY();
> 90123456789012345
> rows: 1
SELECT * FROM INFORMATION_SCHEMA.SEQUENCES;
> SEQUENCE_CATALOG SEQUENCE_SCHEMA SEQUENCE_NAME CURRENT_VALUE INCREMENT IS_GENERATED REMARKS
> ---------------- --------------- ------------- ----------------- --------- ------------ -------
> SCRIPT PUBLIC TEST_LONG 90123456789012345 -1 FALSE
SELECT SEQUENCE_NAME, CURRENT_VALUE, INCREMENT FROM INFORMATION_SCHEMA.SEQUENCES;
> SEQUENCE_NAME CURRENT_VALUE INCREMENT
> ------------- ----------------- ---------
> TEST_LONG 90123456789012345 -1
> rows: 1
SET AUTOCOMMIT TRUE;
......@@ -6734,9 +6734,9 @@ SCRIPT NOPASSWORDS NOSETTINGS;
> CREATE USER IF NOT EXISTS TEST_ADMIN PASSWORD '' ADMIN
> rows: 10
SELECT * FROM INFORMATION_SCHEMA.USERS;
> NAME ADMIN REMARKS
> ---------- ----- -------
SELECT NAME, ADMIN FROM INFORMATION_SCHEMA.USERS;
> NAME ADMIN
> ---------- -----
> SA true
> TEST 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);
insert into test_table values(1);
create view test_view AS SELECT * FROM (SELECT DISTINCT * FROM test_table) AS subquery;
......
......@@ -134,6 +134,7 @@ public class TestScriptReader extends TestBase {
check(source.readStatement(),"/*;\n*/");
check(source.readStatement(),"//;\na");
check(source.readStatement(), null);
source.close();
}
}
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论