h2-insert语句流程分析

1
INSERT INTO TEST(ID, NAME) VALUES(3000, 'aaa');

解析得到Insert命令

1
2
3
4
5
6
7
8
9
10
org.h2.jdbc.JdbcStatement#execute(java.lang.String)
->org.h2.jdbc.JdbcStatement#executeInternal
->org.h2.jdbc.JdbcConnection#prepareCommand(java.lang.String, int)
->org.h2.engine.Session#prepareCommand
->org.h2.engine.Session#prepareLocal
->org.h2.command.Parser#prepareCommand
->org.h2.command.Parser#parse(java.lang.String)
->org.h2.command.Parser#parse(java.lang.String, boolean)
->org.h2.command.Parser#parsePrepared
->org.h2.command.Parser#parseInsert

关键步骤是进入 org.h2.command.Parser#parseInsert 新建了一个Insert命令

  • 校验insert的表是否存在

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    private Table readTableOrView(String tableName) {
    if (schemaName != null) {
    Table table = getSchema().resolveTableOrView(session, tableName);
    if (table != null) {
    return table;
    }
    } else {
    //首先查看 PUBLIC Schema里的tablesAndViews 是否存在key为tableName
    Table table = database.getSchema(session.getCurrentSchemaName())
    .resolveTableOrView(session, tableName);
    if (table != null) {
    return table;
    }
    //遍历该session对应Schema 中tablesAndViews 是否存在key为tableName
    String[] schemaNames = session.getSchemaSearchPath();
    if (schemaNames != null) {
    for (String name : schemaNames) {
    Schema s = database.getSchema(name);
    table = s.resolveTableOrView(session, tableName);
    if (table != null) {
    return table;
    }
    }
    }
    }
    if (isDualTable(tableName)) {
    return new DualTable(database);
    }
    //不存在则抛异常 不能insert一个数据库不存在的表吧^_^
    throw DbException.get(ErrorCode.TABLE_OR_VIEW_NOT_FOUND_1, tableName);
    }