mirror of
https://github.com/MariaDB/server.git
synced 2025-08-31 22:22:30 +03:00
Nuke all of the old_* directories in the ndb tree.
BitKeeper/deleted/.del-Makefile~6c2778d2bf4954a2: Delete: storage/ndb/src/old_files/client/Makefile BitKeeper/deleted/.del-Extra.mk~eabbb28986ca817d: Delete: storage/ndb/src/old_files/client/odbc/Extra.mk BitKeeper/deleted/.del-Makefile~9bc928a18aa88d66: Delete: storage/ndb/src/old_files/client/odbc/Makefile BitKeeper/deleted/.del-NdbOdbc.cpp~aa491b06c9172d11: Delete: storage/ndb/src/old_files/client/odbc/NdbOdbc.cpp BitKeeper/deleted/.del-NdbOdbc.def~cd3eed2c4a0121e9: Delete: storage/ndb/src/old_files/client/odbc/NdbOdbc.def BitKeeper/deleted/.del-CodeGen.cpp~170c83c0765b9160: Delete: storage/ndb/src/old_files/client/odbc/codegen/CodeGen.cpp BitKeeper/deleted/.del-CodeGen.hpp~738f834f80cceba8: Delete: storage/ndb/src/old_files/client/odbc/codegen/CodeGen.hpp BitKeeper/deleted/.del-Code_base.cpp~96f8ceaac8138bfe: Delete: storage/ndb/src/old_files/client/odbc/codegen/Code_base.cpp BitKeeper/deleted/.del-Code_base.hpp~794baaed32588409: Delete: storage/ndb/src/old_files/client/odbc/codegen/Code_base.hpp BitKeeper/deleted/.del-Code_column.cpp~5dd0e5c1215bd8bf: Delete: storage/ndb/src/old_files/client/odbc/codegen/Code_column.cpp BitKeeper/deleted/.del-Code_column.hpp~5d5816d1c496e588: Delete: storage/ndb/src/old_files/client/odbc/codegen/Code_column.hpp BitKeeper/deleted/.del-Code_comp_op.cpp~6ab02cc3b1e08985: Delete: storage/ndb/src/old_files/client/odbc/codegen/Code_comp_op.cpp BitKeeper/deleted/.del-Code_comp_op.hpp~37cf1e4cee3a6bf1: Delete: storage/ndb/src/old_files/client/odbc/codegen/Code_comp_op.hpp BitKeeper/deleted/.del-Code_create_index.cpp~d1f95c5917afab9: Delete: storage/ndb/src/old_files/client/odbc/codegen/Code_create_index.cpp BitKeeper/deleted/.del-Code_create_index.hpp~12bcb33350fc35c1: Delete: storage/ndb/src/old_files/client/odbc/codegen/Code_create_index.hpp BitKeeper/deleted/.del-Code_create_row.cpp~33f73454f8ddf2d5: Delete: storage/ndb/src/old_files/client/odbc/codegen/Code_create_row.cpp BitKeeper/deleted/.del-Code_create_row.hpp~38cb00cc1baa9ee7: Delete: storage/ndb/src/old_files/client/odbc/codegen/Code_create_row.hpp BitKeeper/deleted/.del-Code_create_table.cpp~c25e7cc06414a927: Delete: storage/ndb/src/old_files/client/odbc/codegen/Code_create_table.cpp BitKeeper/deleted/.del-Code_create_table.hpp~9648f467f3f0418e: Delete: storage/ndb/src/old_files/client/odbc/codegen/Code_create_table.hpp BitKeeper/deleted/.del-Code_data_type.cpp~9e46a7ef85345d4: Delete: storage/ndb/src/old_files/client/odbc/codegen/Code_data_type.cpp BitKeeper/deleted/.del-Code_data_type.hpp~5e8928968d3c0107: Delete: storage/ndb/src/old_files/client/odbc/codegen/Code_data_type.hpp BitKeeper/deleted/.del-Code_ddl.cpp~c38ee5368efaf688: Delete: storage/ndb/src/old_files/client/odbc/codegen/Code_ddl.cpp BitKeeper/deleted/.del-Code_ddl.hpp~75482ddd87b65036: Delete: storage/ndb/src/old_files/client/odbc/codegen/Code_ddl.hpp BitKeeper/deleted/.del-Code_ddl_column.cpp~c524862773dd9f38: Delete: storage/ndb/src/old_files/client/odbc/codegen/Code_ddl_column.cpp BitKeeper/deleted/.del-Code_ddl_column.hpp~c9e534e381b21599: Delete: storage/ndb/src/old_files/client/odbc/codegen/Code_ddl_column.hpp BitKeeper/deleted/.del-Code_ddl_constr.cpp~80ae32f83a6c2f00: Delete: storage/ndb/src/old_files/client/odbc/codegen/Code_ddl_constr.cpp BitKeeper/deleted/.del-Code_ddl_constr.hpp~bca16806c57bc97e: Delete: storage/ndb/src/old_files/client/odbc/codegen/Code_ddl_constr.hpp BitKeeper/deleted/.del-Code_ddl_row.cpp~ec2fbc3b8ab08a52: Delete: storage/ndb/src/old_files/client/odbc/codegen/Code_ddl_row.cpp BitKeeper/deleted/.del-Code_ddl_row.hpp~c18a43b3770ad25a: Delete: storage/ndb/src/old_files/client/odbc/codegen/Code_ddl_row.hpp BitKeeper/deleted/.del-Code_delete.cpp~feac77b440d04327: Delete: storage/ndb/src/old_files/client/odbc/codegen/Code_delete.cpp BitKeeper/deleted/.del-Code_delete.hpp~c852ee069a761aab: Delete: storage/ndb/src/old_files/client/odbc/codegen/Code_delete.hpp BitKeeper/deleted/.del-Code_delete_index.cpp~17ed96eca90fe4e7: Delete: storage/ndb/src/old_files/client/odbc/codegen/Code_delete_index.cpp BitKeeper/deleted/.del-Code_delete_index.hpp~18a9bb119b04636: Delete: storage/ndb/src/old_files/client/odbc/codegen/Code_delete_index.hpp BitKeeper/deleted/.del-Code_delete_lookup.cpp~1a3728f8c896684: Delete: storage/ndb/src/old_files/client/odbc/codegen/Code_delete_lookup.cpp BitKeeper/deleted/.del-Code_delete_lookup.hpp~1be71525ed9ee69: Delete: storage/ndb/src/old_files/client/odbc/codegen/Code_delete_lookup.hpp BitKeeper/deleted/.del-Code_delete_scan.cpp~b040ad7670c24eb5: Delete: storage/ndb/src/old_files/client/odbc/codegen/Code_delete_scan.cpp BitKeeper/deleted/.del-Code_delete_scan.hpp~b9a11b4ec895d159: Delete: storage/ndb/src/old_files/client/odbc/codegen/Code_delete_scan.hpp BitKeeper/deleted/.del-Code_dml.cpp~6826ad60f0f566e7: Delete: storage/ndb/src/old_files/client/odbc/codegen/Code_dml.cpp BitKeeper/deleted/.del-Code_dml.hpp~8fdbf19ad3174ca2: Delete: storage/ndb/src/old_files/client/odbc/codegen/Code_dml.hpp BitKeeper/deleted/.del-Code_dml_column.cpp~b71ce6186edf1655: Delete: storage/ndb/src/old_files/client/odbc/codegen/Code_dml_column.cpp BitKeeper/deleted/.del-Code_dml_column.hpp~a843b3418b30b7a3: Delete: storage/ndb/src/old_files/client/odbc/codegen/Code_dml_column.hpp BitKeeper/deleted/.del-Code_dml_row.cpp~17c791507b36cc06: Delete: storage/ndb/src/old_files/client/odbc/codegen/Code_dml_row.cpp BitKeeper/deleted/.del-Code_dml_row.hpp~33c4cffdd238728d: Delete: storage/ndb/src/old_files/client/odbc/codegen/Code_dml_row.hpp BitKeeper/deleted/.del-Code_drop_index.cpp~fc5cab67ae58d9f6: Delete: storage/ndb/src/old_files/client/odbc/codegen/Code_drop_index.cpp BitKeeper/deleted/.del-Code_drop_index.hpp~377c9eb280ec2ee2: Delete: storage/ndb/src/old_files/client/odbc/codegen/Code_drop_index.hpp BitKeeper/deleted/.del-Code_drop_table.cpp~9637d93efa68996a: Delete: storage/ndb/src/old_files/client/odbc/codegen/Code_drop_table.cpp BitKeeper/deleted/.del-Code_drop_table.hpp~d671379125e4bbbe: Delete: storage/ndb/src/old_files/client/odbc/codegen/Code_drop_table.hpp BitKeeper/deleted/.del-Code_expr.cpp~fafd271880c70cf3: Delete: storage/ndb/src/old_files/client/odbc/codegen/Code_expr.cpp BitKeeper/deleted/.del-Code_expr.hpp~9e8243e99e0ec84: Delete: storage/ndb/src/old_files/client/odbc/codegen/Code_expr.hpp BitKeeper/deleted/.del-Code_expr_column.cpp~4c4fbcd5741cc8cf: Delete: storage/ndb/src/old_files/client/odbc/codegen/Code_expr_column.cpp BitKeeper/deleted/.del-Code_expr_column.hpp~9c4cbbdf432dc475: Delete: storage/ndb/src/old_files/client/odbc/codegen/Code_expr_column.hpp BitKeeper/deleted/.del-Code_expr_const.cpp~bdb29dcd94ac5e73: Delete: storage/ndb/src/old_files/client/odbc/codegen/Code_expr_const.cpp BitKeeper/deleted/.del-Code_expr_const.hpp~9c8789cff376b832: Delete: storage/ndb/src/old_files/client/odbc/codegen/Code_expr_const.hpp BitKeeper/deleted/.del-Code_expr_conv.cpp~d252fbfe8ef55fff: Delete: storage/ndb/src/old_files/client/odbc/codegen/Code_expr_conv.cpp BitKeeper/deleted/.del-Code_expr_conv.hpp~5cbea39eecb92a43: Delete: storage/ndb/src/old_files/client/odbc/codegen/Code_expr_conv.hpp BitKeeper/deleted/.del-Code_expr_func.cpp~5d3996f062fa3f52: Delete: storage/ndb/src/old_files/client/odbc/codegen/Code_expr_func.cpp BitKeeper/deleted/.del-Code_expr_func.hpp~22aee1e4f92c49b9: Delete: storage/ndb/src/old_files/client/odbc/codegen/Code_expr_func.hpp BitKeeper/deleted/.del-Code_expr_op.cpp~e1aaa0244f2efa4: Delete: storage/ndb/src/old_files/client/odbc/codegen/Code_expr_op.cpp BitKeeper/deleted/.del-Code_expr_op.hpp~4eb8c02dd0602f: Delete: storage/ndb/src/old_files/client/odbc/codegen/Code_expr_op.hpp BitKeeper/deleted/.del-Code_expr_param.cpp~a5e94ee7c5821611: Delete: storage/ndb/src/old_files/client/odbc/codegen/Code_expr_param.cpp BitKeeper/deleted/.del-Code_expr_param.hpp~ec441ad8ef21aa2b: Delete: storage/ndb/src/old_files/client/odbc/codegen/Code_expr_param.hpp BitKeeper/deleted/.del-Code_expr_row.cpp~bc73d8f9c681d418: Delete: storage/ndb/src/old_files/client/odbc/codegen/Code_expr_row.cpp BitKeeper/deleted/.del-Code_expr_row.hpp~c541c49ea8c0c4f2: Delete: storage/ndb/src/old_files/client/odbc/codegen/Code_expr_row.hpp BitKeeper/deleted/.del-Code_idx_column.cpp~7d4d074ce5daea0a: Delete: storage/ndb/src/old_files/client/odbc/codegen/Code_idx_column.cpp BitKeeper/deleted/.del-Code_idx_column.hpp~caabaafa34722be7: Delete: storage/ndb/src/old_files/client/odbc/codegen/Code_idx_column.hpp BitKeeper/deleted/.del-Code_insert.cpp~7d0ef7cc8f657fd5: Delete: storage/ndb/src/old_files/client/odbc/codegen/Code_insert.cpp BitKeeper/deleted/.del-Code_insert.hpp~cc96fa9b81169471: Delete: storage/ndb/src/old_files/client/odbc/codegen/Code_insert.hpp BitKeeper/deleted/.del-Code_pred.cpp~56faa755aa42ddfa: Delete: storage/ndb/src/old_files/client/odbc/codegen/Code_pred.cpp BitKeeper/deleted/.del-Code_pred.hpp~eada43753e8b1e6c: Delete: storage/ndb/src/old_files/client/odbc/codegen/Code_pred.hpp BitKeeper/deleted/.del-Code_pred_op.cpp~47d693dde1a6d907: Delete: storage/ndb/src/old_files/client/odbc/codegen/Code_pred_op.cpp BitKeeper/deleted/.del-Code_pred_op.hpp~b42256983d2bda7b: Delete: storage/ndb/src/old_files/client/odbc/codegen/Code_pred_op.hpp BitKeeper/deleted/.del-Code_query.cpp~4ac293821c9b4602: Delete: storage/ndb/src/old_files/client/odbc/codegen/Code_query.cpp BitKeeper/deleted/.del-Code_query.hpp~f86fbd9a108206c0: Delete: storage/ndb/src/old_files/client/odbc/codegen/Code_query.hpp BitKeeper/deleted/.del-Code_query_count.cpp~9fa96a57d2dde660: Delete: storage/ndb/src/old_files/client/odbc/codegen/Code_query_count.cpp BitKeeper/deleted/.del-Code_query_count.hpp~bdbe6e4734abc0c5: Delete: storage/ndb/src/old_files/client/odbc/codegen/Code_query_count.hpp BitKeeper/deleted/.del-Code_query_distinct.cpp~3ba18528aa67b9dd: Delete: storage/ndb/src/old_files/client/odbc/codegen/Code_query_distinct.cpp BitKeeper/deleted/.del-Code_query_distinct.hpp~c12b2b7ff6b2e7b3: Delete: storage/ndb/src/old_files/client/odbc/codegen/Code_query_distinct.hpp BitKeeper/deleted/.del-Code_query_filter.cpp~a3d067d5d8fb40c: Delete: storage/ndb/src/old_files/client/odbc/codegen/Code_query_filter.cpp BitKeeper/deleted/.del-Code_query_filter.hpp~d0a341f2e40f0183: Delete: storage/ndb/src/old_files/client/odbc/codegen/Code_query_filter.hpp BitKeeper/deleted/.del-Code_query_group.cpp~4443c844308f9a98: Delete: storage/ndb/src/old_files/client/odbc/codegen/Code_query_group.cpp BitKeeper/deleted/.del-Code_query_group.hpp~ba4691be942c6e2a: Delete: storage/ndb/src/old_files/client/odbc/codegen/Code_query_group.hpp BitKeeper/deleted/.del-Code_query_index.cpp~f0312c9e2f22daf6: Delete: storage/ndb/src/old_files/client/odbc/codegen/Code_query_index.cpp BitKeeper/deleted/.del-Code_query_index.hpp~6baaf1abbb704bb1: Delete: storage/ndb/src/old_files/client/odbc/codegen/Code_query_index.hpp BitKeeper/deleted/.del-Code_query_join.cpp~36e07422c67d6838: Delete: storage/ndb/src/old_files/client/odbc/codegen/Code_query_join.cpp BitKeeper/deleted/.del-Code_query_join.hpp~c4d17d18c4e3b4a0: Delete: storage/ndb/src/old_files/client/odbc/codegen/Code_query_join.hpp BitKeeper/deleted/.del-Code_query_lookup.cpp~3d80e3ddbdae531d: Delete: storage/ndb/src/old_files/client/odbc/codegen/Code_query_lookup.cpp BitKeeper/deleted/.del-Code_query_lookup.hpp~73332533e5196630: Delete: storage/ndb/src/old_files/client/odbc/codegen/Code_query_lookup.hpp BitKeeper/deleted/.del-Code_query_project.cpp~ebc22f71bb7ec98c: Delete: storage/ndb/src/old_files/client/odbc/codegen/Code_query_project.cpp BitKeeper/deleted/.del-Code_query_project.hpp~2734cdf1f907e0a4: Delete: storage/ndb/src/old_files/client/odbc/codegen/Code_query_project.hpp BitKeeper/deleted/.del-Code_query_range.cpp~62ddafd2d17063cc: Delete: storage/ndb/src/old_files/client/odbc/codegen/Code_query_range.cpp BitKeeper/deleted/.del-Code_query_range.hpp~81546843616efefa: Delete: storage/ndb/src/old_files/client/odbc/codegen/Code_query_range.hpp BitKeeper/deleted/.del-Code_query_repeat.cpp~ce8f2a065897d6e3: Delete: storage/ndb/src/old_files/client/odbc/codegen/Code_query_repeat.cpp BitKeeper/deleted/.del-Code_query_repeat.hpp~c20e10d0db9ad53c: Delete: storage/ndb/src/old_files/client/odbc/codegen/Code_query_repeat.hpp BitKeeper/deleted/.del-Code_query_scan.cpp~855e56d6f56de938: Delete: storage/ndb/src/old_files/client/odbc/codegen/Code_query_scan.cpp BitKeeper/deleted/.del-Code_query_scan.hpp~b93c277da5b2509b: Delete: storage/ndb/src/old_files/client/odbc/codegen/Code_query_scan.hpp BitKeeper/deleted/.del-Code_query_sort.cpp~c08fc07f739de097: Delete: storage/ndb/src/old_files/client/odbc/codegen/Code_query_sort.cpp BitKeeper/deleted/.del-Code_query_sort.hpp~84edb5e128eda962: Delete: storage/ndb/src/old_files/client/odbc/codegen/Code_query_sort.hpp BitKeeper/deleted/.del-Code_query_sys.cpp~1d6a4a1cec789001: Delete: storage/ndb/src/old_files/client/odbc/codegen/Code_query_sys.cpp BitKeeper/deleted/.del-Code_query_sys.hpp~f5182823da25f097: Delete: storage/ndb/src/old_files/client/odbc/codegen/Code_query_sys.hpp BitKeeper/deleted/.del-Code_root.cpp~4c26a01ced583e41: Delete: storage/ndb/src/old_files/client/odbc/codegen/Code_root.cpp BitKeeper/deleted/.del-Code_root.hpp~de1fd878505d9e26: Delete: storage/ndb/src/old_files/client/odbc/codegen/Code_root.hpp BitKeeper/deleted/.del-Code_select.cpp~75b2a39f282d8ef5: Delete: storage/ndb/src/old_files/client/odbc/codegen/Code_select.cpp BitKeeper/deleted/.del-Code_select.hpp~f9fadc322d78033a: Delete: storage/ndb/src/old_files/client/odbc/codegen/Code_select.hpp BitKeeper/deleted/.del-Code_set_row.cpp~1bda7e6f86f18aef: Delete: storage/ndb/src/old_files/client/odbc/codegen/Code_set_row.cpp BitKeeper/deleted/.del-Code_set_row.hpp~32ac3de384b91229: Delete: storage/ndb/src/old_files/client/odbc/codegen/Code_set_row.hpp BitKeeper/deleted/.del-Code_stmt.cpp~c0e9903aa90df90b: Delete: storage/ndb/src/old_files/client/odbc/codegen/Code_stmt.cpp BitKeeper/deleted/.del-Code_stmt.hpp~fab11fc487e74d05: Delete: storage/ndb/src/old_files/client/odbc/codegen/Code_stmt.hpp BitKeeper/deleted/.del-Code_table.cpp~c46b7a6e2ecf4f61: Delete: storage/ndb/src/old_files/client/odbc/codegen/Code_table.cpp BitKeeper/deleted/.del-Code_table.hpp~a48d57a0375a6d56: Delete: storage/ndb/src/old_files/client/odbc/codegen/Code_table.hpp BitKeeper/deleted/.del-Code_table_list.cpp~40948eccedfae7bb: Delete: storage/ndb/src/old_files/client/odbc/codegen/Code_table_list.cpp BitKeeper/deleted/.del-Code_table_list.hpp~c1e880e9949d3a: Delete: storage/ndb/src/old_files/client/odbc/codegen/Code_table_list.hpp BitKeeper/deleted/.del-Code_update.cpp~ed36f4a7a928a91b: Delete: storage/ndb/src/old_files/client/odbc/codegen/Code_update.cpp BitKeeper/deleted/.del-Code_update.hpp~c1de760c7b580b0c: Delete: storage/ndb/src/old_files/client/odbc/codegen/Code_update.hpp BitKeeper/deleted/.del-Code_update_index.cpp~a0c6ad33ffbbc00e: Delete: storage/ndb/src/old_files/client/odbc/codegen/Code_update_index.cpp BitKeeper/deleted/.del-Code_update_index.hpp~b57bbe5c8d927df9: Delete: storage/ndb/src/old_files/client/odbc/codegen/Code_update_index.hpp BitKeeper/deleted/.del-Code_update_lookup.cpp~3491782088e97384: Delete: storage/ndb/src/old_files/client/odbc/codegen/Code_update_lookup.cpp BitKeeper/deleted/.del-Code_update_lookup.hpp~ee335822c3496863: Delete: storage/ndb/src/old_files/client/odbc/codegen/Code_update_lookup.hpp BitKeeper/deleted/.del-Code_update_scan.cpp~35e5b7d4619b3e09: Delete: storage/ndb/src/old_files/client/odbc/codegen/Code_update_scan.cpp BitKeeper/deleted/.del-Code_update_scan.hpp~287f193ad48fbefd: Delete: storage/ndb/src/old_files/client/odbc/codegen/Code_update_scan.hpp BitKeeper/deleted/.del-Makefile~420b8378d374f069: Delete: storage/ndb/src/old_files/client/odbc/codegen/Makefile BitKeeper/deleted/.del-SimpleGram.ypp~6301cedf92524710: Delete: storage/ndb/src/old_files/client/odbc/codegen/SimpleGram.ypp BitKeeper/deleted/.del-SimpleParser.cpp~549f93e2a7fd01b5: Delete: storage/ndb/src/old_files/client/odbc/codegen/SimpleParser.cpp BitKeeper/deleted/.del-SimpleParser.hpp~4fdff7ee3839efc4: Delete: storage/ndb/src/old_files/client/odbc/codegen/SimpleParser.hpp BitKeeper/deleted/.del-SimpleScan.lpp~e11862b97fe39faf: Delete: storage/ndb/src/old_files/client/odbc/codegen/SimpleScan.lpp BitKeeper/deleted/.del-AttrArea.cpp~1570da617a1a6c4b: Delete: storage/ndb/src/old_files/client/odbc/common/AttrArea.cpp BitKeeper/deleted/.del-AttrArea.hpp~f3d78ccd37af4e6: Delete: storage/ndb/src/old_files/client/odbc/common/AttrArea.hpp BitKeeper/deleted/.del-CodeTree.cpp~1a4912632b0a61ee: Delete: storage/ndb/src/old_files/client/odbc/common/CodeTree.cpp BitKeeper/deleted/.del-CodeTree.hpp~dcb603cce390eafa: Delete: storage/ndb/src/old_files/client/odbc/common/CodeTree.hpp BitKeeper/deleted/.del-ConnArea.cpp~103182cf445f0bc3: Delete: storage/ndb/src/old_files/client/odbc/common/ConnArea.cpp BitKeeper/deleted/.del-ConnArea.hpp~ffe99deedf7dc1ee: Delete: storage/ndb/src/old_files/client/odbc/common/ConnArea.hpp BitKeeper/deleted/.del-Ctx.cpp~ce1c13ba8a312eba: Delete: storage/ndb/src/old_files/client/odbc/common/Ctx.cpp BitKeeper/deleted/.del-Ctx.hpp~bc88aba55ab71063: Delete: storage/ndb/src/old_files/client/odbc/common/Ctx.hpp BitKeeper/deleted/.del-DataField.cpp~6bb1fe1cb971c8f9: Delete: storage/ndb/src/old_files/client/odbc/common/DataField.cpp BitKeeper/deleted/.del-DataField.hpp~d324898a9a86463d: Delete: storage/ndb/src/old_files/client/odbc/common/DataField.hpp BitKeeper/deleted/.del-DataRow.cpp~8764a23cee4f9481: Delete: storage/ndb/src/old_files/client/odbc/common/DataRow.cpp BitKeeper/deleted/.del-DataRow.hpp~66a65eee1a1b2f23: Delete: storage/ndb/src/old_files/client/odbc/common/DataRow.hpp BitKeeper/deleted/.del-DataType.cpp~29b8ddd51fdd3a2f: Delete: storage/ndb/src/old_files/client/odbc/common/DataType.cpp BitKeeper/deleted/.del-DataType.hpp~adef26bc1dc940eb: Delete: storage/ndb/src/old_files/client/odbc/common/DataType.hpp BitKeeper/deleted/.del-DescArea.cpp~aab4edd7e336acdd: Delete: storage/ndb/src/old_files/client/odbc/common/DescArea.cpp BitKeeper/deleted/.del-DescArea.hpp~20ba9b6484762f0f: Delete: storage/ndb/src/old_files/client/odbc/common/DescArea.hpp BitKeeper/deleted/.del-DiagArea.cpp~e3662d8977947e67: Delete: storage/ndb/src/old_files/client/odbc/common/DiagArea.cpp BitKeeper/deleted/.del-DiagArea.hpp~1c6595b5fac06eb2: Delete: storage/ndb/src/old_files/client/odbc/common/DiagArea.hpp BitKeeper/deleted/.del-Makefile~8505f6b38fe5c219: Delete: storage/ndb/src/old_files/client/odbc/common/Makefile BitKeeper/deleted/.del-OdbcData.cpp~e557009c1ed1e017: Delete: storage/ndb/src/old_files/client/odbc/common/OdbcData.cpp BitKeeper/deleted/.del-OdbcData.hpp~2125814c1293c0b3: Delete: storage/ndb/src/old_files/client/odbc/common/OdbcData.hpp BitKeeper/deleted/.del-ResultArea.cpp~8bcc2a2d9a98b9b0: Delete: storage/ndb/src/old_files/client/odbc/common/ResultArea.cpp BitKeeper/deleted/.del-ResultArea.hpp~8d4646b94be475d1: Delete: storage/ndb/src/old_files/client/odbc/common/ResultArea.hpp BitKeeper/deleted/.del-Sqlstate.cpp~b844144af963c22c: Delete: storage/ndb/src/old_files/client/odbc/common/Sqlstate.cpp BitKeeper/deleted/.del-Sqlstate.hpp~60006ee1c27c6e5: Delete: storage/ndb/src/old_files/client/odbc/common/Sqlstate.hpp BitKeeper/deleted/.del-StmtArea.cpp~5c5f8613156e06b2: Delete: storage/ndb/src/old_files/client/odbc/common/StmtArea.cpp BitKeeper/deleted/.del-StmtArea.hpp~9662e56ae164eb7f: Delete: storage/ndb/src/old_files/client/odbc/common/StmtArea.hpp BitKeeper/deleted/.del-StmtInfo.cpp~54ee4040e5807214: Delete: storage/ndb/src/old_files/client/odbc/common/StmtInfo.cpp BitKeeper/deleted/.del-DictCatalog.cpp~9804b0ff3eac2f8: Delete: storage/ndb/src/old_files/client/odbc/dictionary/DictCatalog.cpp BitKeeper/deleted/.del-DictCatalog.hpp~cace2fb2f6bb65e5: Delete: storage/ndb/src/old_files/client/odbc/dictionary/DictCatalog.hpp BitKeeper/deleted/.del-StmtInfo.hpp~6698d657391692fc: Delete: storage/ndb/src/old_files/client/odbc/common/StmtInfo.hpp BitKeeper/deleted/.del-common.cpp~4792b9ecddd99482: Delete: storage/ndb/src/old_files/client/odbc/common/common.cpp BitKeeper/deleted/.del-common.hpp~25369fa6c80eff53: Delete: storage/ndb/src/old_files/client/odbc/common/common.hpp BitKeeper/deleted/.del-DictColumn.cpp~b69d90c53e5b618: Delete: storage/ndb/src/old_files/client/odbc/dictionary/DictColumn.cpp BitKeeper/deleted/.del-DictColumn.hpp~c2da1b7bd0408bd1: Delete: storage/ndb/src/old_files/client/odbc/dictionary/DictColumn.hpp BitKeeper/deleted/.del-DictIndex.cpp~a456d3039e6a39e3: Delete: storage/ndb/src/old_files/client/odbc/dictionary/DictIndex.cpp BitKeeper/deleted/.del-DictIndex.hpp~f53b91a41bb96663: Delete: storage/ndb/src/old_files/client/odbc/dictionary/DictIndex.hpp BitKeeper/deleted/.del-DictSchema.cpp~639403c84a47dfdd: Delete: storage/ndb/src/old_files/client/odbc/dictionary/DictSchema.cpp BitKeeper/deleted/.del-DictSchema.hpp~5aa7dc8ade17e94c: Delete: storage/ndb/src/old_files/client/odbc/dictionary/DictSchema.hpp BitKeeper/deleted/.del-DictSys.cpp~fb89465b10c32bb0: Delete: storage/ndb/src/old_files/client/odbc/dictionary/DictSys.cpp BitKeeper/deleted/.del-DictSys.hpp~76583ba8aa88fd6f: Delete: storage/ndb/src/old_files/client/odbc/dictionary/DictSys.hpp BitKeeper/deleted/.del-DictTable.cpp~8f4a9ee5a8038f87: Delete: storage/ndb/src/old_files/client/odbc/dictionary/DictTable.cpp BitKeeper/deleted/.del-DictTable.hpp~cf99a9ac3dd49206: Delete: storage/ndb/src/old_files/client/odbc/dictionary/DictTable.hpp BitKeeper/deleted/.del-Makefile~4c1a6148787bdc2f: Delete: storage/ndb/src/old_files/client/odbc/dictionary/Makefile BitKeeper/deleted/.del-class.fig~c0754ccad74d380a: Delete: storage/ndb/src/old_files/client/odbc/docs/class.fig BitKeeper/deleted/.del-descfield.pl~e0bd59c2824824cc: Delete: storage/ndb/src/old_files/client/odbc/docs/descfield.pl BitKeeper/deleted/.del-diag.txt~b66a7e227391335f: Delete: storage/ndb/src/old_files/client/odbc/docs/diag.txt BitKeeper/deleted/.del-getinfo.pl~2142ecf1567a66f6: Delete: storage/ndb/src/old_files/client/odbc/docs/getinfo.pl BitKeeper/deleted/.del-gettypeinfo.pl~2ea4c0589eac4e73: Delete: storage/ndb/src/old_files/client/odbc/docs/gettypeinfo.pl BitKeeper/deleted/.del-handleattr.pl~b0c2a2901b68342e: Delete: storage/ndb/src/old_files/client/odbc/docs/handleattr.pl BitKeeper/deleted/.del-main.hpp~7b15eb7ffad488a0: Delete: storage/ndb/src/old_files/client/odbc/docs/main.hpp BitKeeper/deleted/.del-ndbodbc.html~a2f14fdd978b62cc: Delete: storage/ndb/src/old_files/client/odbc/docs/ndbodbc.html BitKeeper/deleted/.del-select.fig~34f5222b5012e1d7: Delete: storage/ndb/src/old_files/client/odbc/docs/select.fig BitKeeper/deleted/.del-Func.data~9e75f15d921063f3: Delete: storage/ndb/src/old_files/client/odbc/driver/Func.data BitKeeper/deleted/.del-Func.pl~aefb901bc3941d32: Delete: storage/ndb/src/old_files/client/odbc/driver/Func.pl BitKeeper/deleted/.del-systables.pl~1fa2191648bdb629: Delete: storage/ndb/src/old_files/client/odbc/docs/systables.pl BitKeeper/deleted/.del-type.txt~feec700c81f5095f: Delete: storage/ndb/src/old_files/client/odbc/docs/type.txt BitKeeper/deleted/.del-Makefile~80d21270fc3ad931: Delete: storage/ndb/src/old_files/client/odbc/driver/Makefile BitKeeper/deleted/.del-SQLAllocConnect.cpp~246af836b028d810: Delete: storage/ndb/src/old_files/client/odbc/driver/SQLAllocConnect.cpp BitKeeper/deleted/.del-SQLAllocEnv.cpp~eaf36cf2285ec2ac: Delete: storage/ndb/src/old_files/client/odbc/driver/SQLAllocEnv.cpp BitKeeper/deleted/.del-SQLAllocHandle.cpp~c0921921e84d1a10: Delete: storage/ndb/src/old_files/client/odbc/driver/SQLAllocHandle.cpp BitKeeper/deleted/.del-SQLAllocHandleStd.cpp~7d145f6e3640d913: Delete: storage/ndb/src/old_files/client/odbc/driver/SQLAllocHandleStd.cpp BitKeeper/deleted/.del-SQLAllocStmt.cpp~362331ef456ec879: Delete: storage/ndb/src/old_files/client/odbc/driver/SQLAllocStmt.cpp BitKeeper/deleted/.del-SQLBindCol.cpp~fec3a78088d4951d: Delete: storage/ndb/src/old_files/client/odbc/driver/SQLBindCol.cpp BitKeeper/deleted/.del-SQLBindParam.cpp~a50b619a23efaab: Delete: storage/ndb/src/old_files/client/odbc/driver/SQLBindParam.cpp BitKeeper/deleted/.del-SQLBindParameter.cpp~533b1992496e2775: Delete: storage/ndb/src/old_files/client/odbc/driver/SQLBindParameter.cpp BitKeeper/deleted/.del-SQLBrowseConnect.cpp~120b61a1ff6edee3: Delete: storage/ndb/src/old_files/client/odbc/driver/SQLBrowseConnect.cpp BitKeeper/deleted/.del-SQLBulkOperations.cpp~7a96be04250a388: Delete: storage/ndb/src/old_files/client/odbc/driver/SQLBulkOperations.cpp BitKeeper/deleted/.del-SQLCancel.cpp~27eab683f6fa6ec6: Delete: storage/ndb/src/old_files/client/odbc/driver/SQLCancel.cpp BitKeeper/deleted/.del-SQLCloseCursor.cpp~6cbf193aadaf1058: Delete: storage/ndb/src/old_files/client/odbc/driver/SQLCloseCursor.cpp BitKeeper/deleted/.del-SQLColAttribute.cpp~f2c858b16a9360d: Delete: storage/ndb/src/old_files/client/odbc/driver/SQLColAttribute.cpp BitKeeper/deleted/.del-SQLColAttributes.cpp~d4007908ee1309d: Delete: storage/ndb/src/old_files/client/odbc/driver/SQLColAttributes.cpp BitKeeper/deleted/.del-SQLColumnPrivileges.cpp~39a3020da4c3485b: Delete: storage/ndb/src/old_files/client/odbc/driver/SQLColumnPrivileges.cpp BitKeeper/deleted/.del-SQLColumns.cpp~1c31107df60bb544: Delete: storage/ndb/src/old_files/client/odbc/driver/SQLColumns.cpp BitKeeper/deleted/.del-SQLConnect.cpp~868e02a519b72743: Delete: storage/ndb/src/old_files/client/odbc/driver/SQLConnect.cpp BitKeeper/deleted/.del-SQLCopyDesc.cpp~286522b25a029761: Delete: storage/ndb/src/old_files/client/odbc/driver/SQLCopyDesc.cpp BitKeeper/deleted/.del-SQLDataSources.cpp~12792108aac5b2ca: Delete: storage/ndb/src/old_files/client/odbc/driver/SQLDataSources.cpp BitKeeper/deleted/.del-SQLDescribeCol.cpp~1d1faafbcd3ecb3c: Delete: storage/ndb/src/old_files/client/odbc/driver/SQLDescribeCol.cpp BitKeeper/deleted/.del-SQLDescribeParam.cpp~70b016fa795ed275: Delete: storage/ndb/src/old_files/client/odbc/driver/SQLDescribeParam.cpp BitKeeper/deleted/.del-SQLDisconnect.cpp~9fb4c3d7a84db50a: Delete: storage/ndb/src/old_files/client/odbc/driver/SQLDisconnect.cpp BitKeeper/deleted/.del-SQLDriverConnect.cpp~8dad42af7d17a9d9: Delete: storage/ndb/src/old_files/client/odbc/driver/SQLDriverConnect.cpp BitKeeper/deleted/.del-SQLDrivers.cpp~400e7453e70f6e99: Delete: storage/ndb/src/old_files/client/odbc/driver/SQLDrivers.cpp BitKeeper/deleted/.del-SQLEndTran.cpp~c37cce04cc303c01: Delete: storage/ndb/src/old_files/client/odbc/driver/SQLEndTran.cpp BitKeeper/deleted/.del-SQLError.cpp~593b81885c15187b: Delete: storage/ndb/src/old_files/client/odbc/driver/SQLError.cpp BitKeeper/deleted/.del-SQLExecDirect.cpp~5e6274e76315339d: Delete: storage/ndb/src/old_files/client/odbc/driver/SQLExecDirect.cpp BitKeeper/deleted/.del-SQLExecute.cpp~1692a85f8639f71: Delete: storage/ndb/src/old_files/client/odbc/driver/SQLExecute.cpp BitKeeper/deleted/.del-SQLExtendedFetch.cpp~8b9d604580a83cfd: Delete: storage/ndb/src/old_files/client/odbc/driver/SQLExtendedFetch.cpp BitKeeper/deleted/.del-SQLFetch.cpp~fa1606aa2dd901db: Delete: storage/ndb/src/old_files/client/odbc/driver/SQLFetch.cpp BitKeeper/deleted/.del-SQLFetchScroll.cpp~cdb16803511963a1: Delete: storage/ndb/src/old_files/client/odbc/driver/SQLFetchScroll.cpp BitKeeper/deleted/.del-SQLForeignKeys.cpp~4b8a9af2f6bf92cb: Delete: storage/ndb/src/old_files/client/odbc/driver/SQLForeignKeys.cpp BitKeeper/deleted/.del-SQLFreeConnect.cpp~92359420501ebc5b: Delete: storage/ndb/src/old_files/client/odbc/driver/SQLFreeConnect.cpp BitKeeper/deleted/.del-SQLFreeEnv.cpp~64f1776817464807: Delete: storage/ndb/src/old_files/client/odbc/driver/SQLFreeEnv.cpp BitKeeper/deleted/.del-SQLFreeHandle.cpp~2dc029edf912c2d: Delete: storage/ndb/src/old_files/client/odbc/driver/SQLFreeHandle.cpp BitKeeper/deleted/.del-SQLFreeStmt.cpp~8f8cb0a43c02a67: Delete: storage/ndb/src/old_files/client/odbc/driver/SQLFreeStmt.cpp BitKeeper/deleted/.del-SQLGetConnectAttr.cpp~b29ff18aeedd8966: Delete: storage/ndb/src/old_files/client/odbc/driver/SQLGetConnectAttr.cpp BitKeeper/deleted/.del-SQLGetConnectOption.cpp~3e0bc4e1af95c682: Delete: storage/ndb/src/old_files/client/odbc/driver/SQLGetConnectOption.cpp BitKeeper/deleted/.del-SQLGetCursorName.cpp~8266b920671b6d01: Delete: storage/ndb/src/old_files/client/odbc/driver/SQLGetCursorName.cpp BitKeeper/deleted/.del-SQLGetData.cpp~3d837348460c219d: Delete: storage/ndb/src/old_files/client/odbc/driver/SQLGetData.cpp BitKeeper/deleted/.del-SQLGetDescField.cpp~62828192a7d1d954: Delete: storage/ndb/src/old_files/client/odbc/driver/SQLGetDescField.cpp BitKeeper/deleted/.del-SQLGetDescRec.cpp~f54cc69bcd1238ad: Delete: storage/ndb/src/old_files/client/odbc/driver/SQLGetDescRec.cpp BitKeeper/deleted/.del-SQLGetDiagField.cpp~673e1ea0f9d5121f: Delete: storage/ndb/src/old_files/client/odbc/driver/SQLGetDiagField.cpp BitKeeper/deleted/.del-SQLGetDiagRec.cpp~bea0f68f5b940ab8: Delete: storage/ndb/src/old_files/client/odbc/driver/SQLGetDiagRec.cpp BitKeeper/deleted/.del-SQLGetEnvAttr.cpp~e742277d8bdf234d: Delete: storage/ndb/src/old_files/client/odbc/driver/SQLGetEnvAttr.cpp BitKeeper/deleted/.del-SQLGetFunctions.cpp~72de050fbfb4a9bb: Delete: storage/ndb/src/old_files/client/odbc/driver/SQLGetFunctions.cpp BitKeeper/deleted/.del-SQLGetInfo.cpp~e4e09d6bedbf02b1: Delete: storage/ndb/src/old_files/client/odbc/driver/SQLGetInfo.cpp BitKeeper/deleted/.del-SQLGetStmtAttr.cpp~de7dabc8c2acea7: Delete: storage/ndb/src/old_files/client/odbc/driver/SQLGetStmtAttr.cpp BitKeeper/deleted/.del-SQLGetStmtOption.cpp~2ff900ebdd167077: Delete: storage/ndb/src/old_files/client/odbc/driver/SQLGetStmtOption.cpp BitKeeper/deleted/.del-SQLGetTypeInfo.cpp~333196b07473dff6: Delete: storage/ndb/src/old_files/client/odbc/driver/SQLGetTypeInfo.cpp BitKeeper/deleted/.del-SQLMoreResults.cpp~483d94cb57379e81: Delete: storage/ndb/src/old_files/client/odbc/driver/SQLMoreResults.cpp BitKeeper/deleted/.del-SQLNativeSql.cpp~eeae6067f4a85c: Delete: storage/ndb/src/old_files/client/odbc/driver/SQLNativeSql.cpp BitKeeper/deleted/.del-SQLNumParams.cpp~8921304c3bcf4835: Delete: storage/ndb/src/old_files/client/odbc/driver/SQLNumParams.cpp BitKeeper/deleted/.del-SQLNumResultCols.cpp~4d2b6527ffe81059: Delete: storage/ndb/src/old_files/client/odbc/driver/SQLNumResultCols.cpp BitKeeper/deleted/.del-SQLParamData.cpp~163b046513f1e4ae: Delete: storage/ndb/src/old_files/client/odbc/driver/SQLParamData.cpp BitKeeper/deleted/.del-SQLParamOptions.cpp~bdcbccb961fff044: Delete: storage/ndb/src/old_files/client/odbc/driver/SQLParamOptions.cpp BitKeeper/deleted/.del-SQLPrepare.cpp~1d339fe24888087: Delete: storage/ndb/src/old_files/client/odbc/driver/SQLPrepare.cpp BitKeeper/deleted/.del-SQLPrimaryKeys.cpp~5d7b2a0ae08a267: Delete: storage/ndb/src/old_files/client/odbc/driver/SQLPrimaryKeys.cpp BitKeeper/deleted/.del-SQLProcedureColumns.cpp~c7a0535e9f50ff39: Delete: storage/ndb/src/old_files/client/odbc/driver/SQLProcedureColumns.cpp BitKeeper/deleted/.del-SQLProcedures.cpp~c59d025b22e2d1a6: Delete: storage/ndb/src/old_files/client/odbc/driver/SQLProcedures.cpp BitKeeper/deleted/.del-SQLPutData.cpp~9dbf69ea9d369dbd: Delete: storage/ndb/src/old_files/client/odbc/driver/SQLPutData.cpp BitKeeper/deleted/.del-SQLRowCount.cpp~d4ac5b273afdb154: Delete: storage/ndb/src/old_files/client/odbc/driver/SQLRowCount.cpp BitKeeper/deleted/.del-SQLSetConnectAttr.cpp~c2c520c34c41bd88: Delete: storage/ndb/src/old_files/client/odbc/driver/SQLSetConnectAttr.cpp BitKeeper/deleted/.del-SQLSetConnectOption.cpp~dadc980d9f9cad1b: Delete: storage/ndb/src/old_files/client/odbc/driver/SQLSetConnectOption.cpp BitKeeper/deleted/.del-SQLSetCursorName.cpp~ccfc33dd2cf6abeb: Delete: storage/ndb/src/old_files/client/odbc/driver/SQLSetCursorName.cpp BitKeeper/deleted/.del-SQLSetDescField.cpp~c4db694d1b9e8f77: Delete: storage/ndb/src/old_files/client/odbc/driver/SQLSetDescField.cpp BitKeeper/deleted/.del-SQLSetDescRec.cpp~f8dd72467d5012ab: Delete: storage/ndb/src/old_files/client/odbc/driver/SQLSetDescRec.cpp BitKeeper/deleted/.del-SQLSetEnvAttr.cpp~7b50aeae6228c2db: Delete: storage/ndb/src/old_files/client/odbc/driver/SQLSetEnvAttr.cpp BitKeeper/deleted/.del-SQLSetParam.cpp~e0dd2d5e8d3ec450: Delete: storage/ndb/src/old_files/client/odbc/driver/SQLSetParam.cpp BitKeeper/deleted/.del-SQLSetPos.cpp~39a3e69960041aa7: Delete: storage/ndb/src/old_files/client/odbc/driver/SQLSetPos.cpp BitKeeper/deleted/.del-SQLSetScrollOptions.cpp~6f8250379bb0cac8: Delete: storage/ndb/src/old_files/client/odbc/driver/SQLSetScrollOptions.cpp BitKeeper/deleted/.del-SQLSetStmtAttr.cpp~e99b7e6025a1ae1f: Delete: storage/ndb/src/old_files/client/odbc/driver/SQLSetStmtAttr.cpp BitKeeper/deleted/.del-SQLSetStmtOption.cpp~87af3125a48c27fa: Delete: storage/ndb/src/old_files/client/odbc/driver/SQLSetStmtOption.cpp BitKeeper/deleted/.del-SQLSpecialColumns.cpp~1877b4c368825de5: Delete: storage/ndb/src/old_files/client/odbc/driver/SQLSpecialColumns.cpp BitKeeper/deleted/.del-SQLStatistics.cpp~87e0359f237aa66a: Delete: storage/ndb/src/old_files/client/odbc/driver/SQLStatistics.cpp BitKeeper/deleted/.del-SQLTablePrivileges.cpp~fa16ea0fffa4edeb: Delete: storage/ndb/src/old_files/client/odbc/driver/SQLTablePrivileges.cpp BitKeeper/deleted/.del-SQLTables.cpp~c8b201068baec393: Delete: storage/ndb/src/old_files/client/odbc/driver/SQLTables.cpp BitKeeper/deleted/.del-SQLTransact.cpp~eb33c2f66ee85738: Delete: storage/ndb/src/old_files/client/odbc/driver/SQLTransact.cpp BitKeeper/deleted/.del-Exec_comp_op.cpp~eacbd7512b32d68b: Delete: storage/ndb/src/old_files/client/odbc/executor/Exec_comp_op.cpp BitKeeper/deleted/.del-Exec_create_index.cpp~c6b8e670198adfa9: Delete: storage/ndb/src/old_files/client/odbc/executor/Exec_create_index.cpp BitKeeper/deleted/.del-driver.cpp~f8f1eeec35b08f18: Delete: storage/ndb/src/old_files/client/odbc/driver/driver.cpp BitKeeper/deleted/.del-driver.hpp~f108f4eef34ec8ea: Delete: storage/ndb/src/old_files/client/odbc/driver/driver.hpp BitKeeper/deleted/.del-Exec_create_table.cpp~76904d417bc0a59a: Delete: storage/ndb/src/old_files/client/odbc/executor/Exec_create_table.cpp BitKeeper/deleted/.del-Exec_delete_index.cpp~1ffe5af6eb160a68: Delete: storage/ndb/src/old_files/client/odbc/executor/Exec_delete_index.cpp BitKeeper/deleted/.del-Exec_delete_lookup.cpp~5d24028ce16b6623: Delete: storage/ndb/src/old_files/client/odbc/executor/Exec_delete_lookup.cpp BitKeeper/deleted/.del-Exec_delete_scan.cpp~810aa4058f73c941: Delete: storage/ndb/src/old_files/client/odbc/executor/Exec_delete_scan.cpp BitKeeper/deleted/.del-Exec_drop_index.cpp~3a3871ec6ee48c28: Delete: storage/ndb/src/old_files/client/odbc/executor/Exec_drop_index.cpp BitKeeper/deleted/.del-Exec_drop_table.cpp~639a2faba4da14f4: Delete: storage/ndb/src/old_files/client/odbc/executor/Exec_drop_table.cpp BitKeeper/deleted/.del-Exec_expr_conv.cpp~b5452bd4fbd7c945: Delete: storage/ndb/src/old_files/client/odbc/executor/Exec_expr_conv.cpp BitKeeper/deleted/.del-Exec_expr_func.cpp~c78ab0e67d54f38c: Delete: storage/ndb/src/old_files/client/odbc/executor/Exec_expr_func.cpp BitKeeper/deleted/.del-Exec_expr_op.cpp~5e341b2e63495ba4: Delete: storage/ndb/src/old_files/client/odbc/executor/Exec_expr_op.cpp BitKeeper/deleted/.del-Exec_insert.cpp~71dd4bf2fb913f2e: Delete: storage/ndb/src/old_files/client/odbc/executor/Exec_insert.cpp BitKeeper/deleted/.del-Exec_pred_op.cpp~ebe7b65ba81e5185: Delete: storage/ndb/src/old_files/client/odbc/executor/Exec_pred_op.cpp BitKeeper/deleted/.del-Exec_query_index.cpp~4cada676fa178001: Delete: storage/ndb/src/old_files/client/odbc/executor/Exec_query_index.cpp BitKeeper/deleted/.del-Exec_query_lookup.cpp~79dfe29b088d832: Delete: storage/ndb/src/old_files/client/odbc/executor/Exec_query_lookup.cpp BitKeeper/deleted/.del-Exec_query_range.cpp~7c4e148e81a292d6: Delete: storage/ndb/src/old_files/client/odbc/executor/Exec_query_range.cpp BitKeeper/deleted/.del-Exec_query_scan.cpp~7c66194f7f93346f: Delete: storage/ndb/src/old_files/client/odbc/executor/Exec_query_scan.cpp BitKeeper/deleted/.del-Exec_query_sys.cpp~d66abe07cd519163: Delete: storage/ndb/src/old_files/client/odbc/executor/Exec_query_sys.cpp BitKeeper/deleted/.del-Exec_update_index.cpp~86140a945f790890: Delete: storage/ndb/src/old_files/client/odbc/executor/Exec_update_index.cpp BitKeeper/deleted/.del-Exec_update_lookup.cpp~b7a7387620cf42ab: Delete: storage/ndb/src/old_files/client/odbc/executor/Exec_update_lookup.cpp BitKeeper/deleted/.del-Exec_update_scan.cpp~2285c72106cffe0: Delete: storage/ndb/src/old_files/client/odbc/executor/Exec_update_scan.cpp BitKeeper/deleted/.del-Executor.cpp~ccb54cc8ffe18bae: Delete: storage/ndb/src/old_files/client/odbc/executor/Executor.cpp BitKeeper/deleted/.del-Executor.hpp~c94d916ae5af2506: Delete: storage/ndb/src/old_files/client/odbc/executor/Executor.hpp BitKeeper/deleted/.del-AttrDbc.cpp~24a034fbb22cdb23: Delete: storage/ndb/src/old_files/client/odbc/handles/AttrDbc.cpp BitKeeper/deleted/.del-AttrEnv.cpp~7d74bcba78e149d0: Delete: storage/ndb/src/old_files/client/odbc/handles/AttrEnv.cpp BitKeeper/deleted/.del-AttrRoot.cpp~5def5d7e228eedf0: Delete: storage/ndb/src/old_files/client/odbc/handles/AttrRoot.cpp BitKeeper/deleted/.del-Makefile~a08f437558c2d3b4: Delete: storage/ndb/src/old_files/client/odbc/executor/Makefile BitKeeper/deleted/.del-AttrStmt.cpp~5363ba63b35ff8f4: Delete: storage/ndb/src/old_files/client/odbc/handles/AttrStmt.cpp BitKeeper/deleted/.del-DescSpec.cpp~cd50c1c855f1905: Delete: storage/ndb/src/old_files/client/odbc/handles/DescSpec.cpp BitKeeper/deleted/.del-FuncTab.cpp~e77abea11a532708: Delete: storage/ndb/src/old_files/client/odbc/handles/FuncTab.cpp BitKeeper/deleted/.del-HandleBase.cpp~2ba63dce2dfec07b: Delete: storage/ndb/src/old_files/client/odbc/handles/HandleBase.cpp BitKeeper/deleted/.del-HandleBase.hpp~8cf9a1e94d272328: Delete: storage/ndb/src/old_files/client/odbc/handles/HandleBase.hpp BitKeeper/deleted/.del-HandleDbc.cpp~2a79fea6477b2c63: Delete: storage/ndb/src/old_files/client/odbc/handles/HandleDbc.cpp BitKeeper/deleted/.del-HandleDbc.hpp~9abc692ac6b0abb3: Delete: storage/ndb/src/old_files/client/odbc/handles/HandleDbc.hpp BitKeeper/deleted/.del-HandleDesc.cpp~e77eb1d73d171a98: Delete: storage/ndb/src/old_files/client/odbc/handles/HandleDesc.cpp BitKeeper/deleted/.del-HandleDesc.hpp~553aeb842b3da88e: Delete: storage/ndb/src/old_files/client/odbc/handles/HandleDesc.hpp BitKeeper/deleted/.del-HandleEnv.cpp~6b96fc6b188f252b: Delete: storage/ndb/src/old_files/client/odbc/handles/HandleEnv.cpp BitKeeper/deleted/.del-HandleEnv.hpp~572a7b4af6816f8b: Delete: storage/ndb/src/old_files/client/odbc/handles/HandleEnv.hpp BitKeeper/deleted/.del-HandleRoot.cpp~aa5044f74554fa9c: Delete: storage/ndb/src/old_files/client/odbc/handles/HandleRoot.cpp BitKeeper/deleted/.del-HandleRoot.hpp~2fcfca742c13cfb3: Delete: storage/ndb/src/old_files/client/odbc/handles/HandleRoot.hpp BitKeeper/deleted/.del-HandleStmt.cpp~782f96bda9eaf13c: Delete: storage/ndb/src/old_files/client/odbc/handles/HandleStmt.cpp BitKeeper/deleted/.del-HandleStmt.hpp~6508fc97f3c772e1: Delete: storage/ndb/src/old_files/client/odbc/handles/HandleStmt.hpp BitKeeper/deleted/.del-InfoTab.cpp~f89104b9c6fe7489: Delete: storage/ndb/src/old_files/client/odbc/handles/InfoTab.cpp BitKeeper/deleted/.del-Makefile~3d8d1529ad26ce76: Delete: storage/ndb/src/old_files/client/odbc/handles/Makefile BitKeeper/deleted/.del-PoolNdb.cpp~793fa032699b7d98: Delete: storage/ndb/src/old_files/client/odbc/handles/PoolNdb.cpp BitKeeper/deleted/.del-PoolNdb.hpp~db9e1a04d2fe705d: Delete: storage/ndb/src/old_files/client/odbc/handles/PoolNdb.hpp BitKeeper/deleted/.del-handles.hpp~bfe0b6a7a95ac142: Delete: storage/ndb/src/old_files/client/odbc/handles/handles.hpp BitKeeper/deleted/.del-Makefile~4b92d5e5b416dd0: Delete: storage/ndb/src/old_files/ndbbaseclient/Makefile BitKeeper/deleted/.del-Makefile~f993f3afae0d4308: Delete: storage/ndb/src/old_files/ndbclient/Makefile BitKeeper/deleted/.del-ndbbaseclient_dummy.cpp~daee9eb6acbc94: Delete: storage/ndb/src/old_files/ndbbaseclient/ndbbaseclient_dummy.cpp BitKeeper/deleted/.del-ndbclient_dummy.cpp~73154070f5d0bfbf: Delete: storage/ndb/src/old_files/ndbclient/ndbclient_dummy.cpp BitKeeper/deleted/.del-Makefile~bcbd9a7282094cc: Delete: storage/ndb/src/old_files/newtonapi/Makefile BitKeeper/deleted/.del-dba_binding.cpp~dcc4fb57f9ab6cba: Delete: storage/ndb/src/old_files/newtonapi/dba_binding.cpp BitKeeper/deleted/.del-dba_bulkread.cpp~4ddfe02a93d2ba11: Delete: storage/ndb/src/old_files/newtonapi/dba_bulkread.cpp BitKeeper/deleted/.del-dba_config.cpp~38acf2ad3a932420: Delete: storage/ndb/src/old_files/newtonapi/dba_config.cpp BitKeeper/deleted/.del-dba_dac.cpp~4615e3d0d8a15bff: Delete: storage/ndb/src/old_files/newtonapi/dba_dac.cpp BitKeeper/deleted/.del-dba_error.cpp~a58b4a1628a2d4b9: Delete: storage/ndb/src/old_files/newtonapi/dba_error.cpp BitKeeper/deleted/.del-dba_init.cpp~80da7e3fa0775346: Delete: storage/ndb/src/old_files/newtonapi/dba_init.cpp BitKeeper/deleted/.del-dba_internal.hpp~54884404e30c8823: Delete: storage/ndb/src/old_files/newtonapi/dba_internal.hpp BitKeeper/deleted/.del-dba_process.cpp~509e54294bc7efd2: Delete: storage/ndb/src/old_files/newtonapi/dba_process.cpp BitKeeper/deleted/.del-ExtSender.cpp~1851d559cfddae43: Delete: storage/ndb/src/old_files/rep/ExtSender.cpp BitKeeper/deleted/.del-ExtSender.hpp~10ae62ec85ee6692: Delete: storage/ndb/src/old_files/rep/ExtSender.hpp BitKeeper/deleted/.del-dba_process.hpp~f0ddefb3b2d6a662: Delete: storage/ndb/src/old_files/newtonapi/dba_process.hpp BitKeeper/deleted/.del-dba_schema.cpp~1c3b8399853c108: Delete: storage/ndb/src/old_files/newtonapi/dba_schema.cpp BitKeeper/deleted/.del-Makefile~954f853c2d812c2c: Delete: storage/ndb/src/old_files/rep/Makefile BitKeeper/deleted/.del-NodeConnectInfo.hpp~9c4318dd55f3f84: Delete: storage/ndb/src/old_files/rep/NodeConnectInfo.hpp BitKeeper/deleted/.del-README~6939b06d192a6b99: Delete: storage/ndb/src/old_files/rep/README BitKeeper/deleted/.del-RepApiInterpreter.cpp~8ba561cb831ae353: Delete: storage/ndb/src/old_files/rep/RepApiInterpreter.cpp BitKeeper/deleted/.del-RepApiInterpreter.hpp~31be5af2ba72d263: Delete: storage/ndb/src/old_files/rep/RepApiInterpreter.hpp BitKeeper/deleted/.del-RepApiService.cpp~93d4005333167a0f: Delete: storage/ndb/src/old_files/rep/RepApiService.cpp BitKeeper/deleted/.del-RepApiService.hpp~42f5ffb7e3baa54e: Delete: storage/ndb/src/old_files/rep/RepApiService.hpp BitKeeper/deleted/.del-RepCommandInterpreter.cpp~f661a8ff312213f8: Delete: storage/ndb/src/old_files/rep/RepCommandInterpreter.cpp BitKeeper/deleted/.del-RepCommandInterpreter.hpp~fb6f22895e8c8679: Delete: storage/ndb/src/old_files/rep/RepCommandInterpreter.hpp BitKeeper/deleted/.del-RepComponents.cpp~fb067aee8e5a4a1f: Delete: storage/ndb/src/old_files/rep/RepComponents.cpp BitKeeper/deleted/.del-RepComponents.hpp~9e632beac4f8bbf8: Delete: storage/ndb/src/old_files/rep/RepComponents.hpp BitKeeper/deleted/.del-RepMain.cpp~de79cb7b6f3acd18: Delete: storage/ndb/src/old_files/rep/RepMain.cpp BitKeeper/deleted/.del-Requestor.cpp~c653fa987f84ce43: Delete: storage/ndb/src/old_files/rep/Requestor.cpp BitKeeper/deleted/.del-Requestor.hpp~a499054c9a128dbd: Delete: storage/ndb/src/old_files/rep/Requestor.hpp BitKeeper/deleted/.del-RequestorSubscriptions.cpp~f0643f7cc9aa9654: Delete: storage/ndb/src/old_files/rep/RequestorSubscriptions.cpp BitKeeper/deleted/.del-SignalQueue.cpp~6d32d876acc1a598: Delete: storage/ndb/src/old_files/rep/SignalQueue.cpp BitKeeper/deleted/.del-AppNDB.cpp~1db5eafacdeda3b7: Delete: storage/ndb/src/old_files/rep/adapters/AppNDB.cpp BitKeeper/deleted/.del-SignalQueue.hpp~b92204ff36f399d1: Delete: storage/ndb/src/old_files/rep/SignalQueue.hpp BitKeeper/deleted/.del-TODO~187896dd2e5dfd02: Delete: storage/ndb/src/old_files/rep/TODO BitKeeper/deleted/.del-dbug_hack.cpp~f090906a24103f0: Delete: storage/ndb/src/old_files/rep/dbug_hack.cpp BitKeeper/deleted/.del-rep_version.hpp~82a23fe4dbb13cab: Delete: storage/ndb/src/old_files/rep/rep_version.hpp BitKeeper/deleted/.del-AppNDB.hpp~2c3081224b4ff75f: Delete: storage/ndb/src/old_files/rep/adapters/AppNDB.hpp BitKeeper/deleted/.del-ExtAPI.cpp~d98f38669b10ca97: Delete: storage/ndb/src/old_files/rep/adapters/ExtAPI.cpp BitKeeper/deleted/.del-ExtAPI.hpp~32bcb96bcd2d60c: Delete: storage/ndb/src/old_files/rep/adapters/ExtAPI.hpp BitKeeper/deleted/.del-ExtNDB.cpp~38cccb80529c02c6: Delete: storage/ndb/src/old_files/rep/adapters/ExtNDB.cpp BitKeeper/deleted/.del-ExtNDB.hpp~ee245e7e2c707685: Delete: storage/ndb/src/old_files/rep/adapters/ExtNDB.hpp BitKeeper/deleted/.del-Makefile~25c4b35b84d945b4: Delete: storage/ndb/src/old_files/rep/repapi/Makefile BitKeeper/deleted/.del-Makefile~bcb9d87fd69a7911: Delete: storage/ndb/src/old_files/rep/adapters/Makefile BitKeeper/deleted/.del-TableInfoPs.hpp~56b1f8f75fe7cb1c: Delete: storage/ndb/src/old_files/rep/adapters/TableInfoPs.hpp BitKeeper/deleted/.del-Channel.cpp~1d5f62245962b839: Delete: storage/ndb/src/old_files/rep/state/Channel.cpp BitKeeper/deleted/.del-Channel.hpp~71c1d63ef4b2cbfe: Delete: storage/ndb/src/old_files/rep/state/Channel.hpp BitKeeper/deleted/.del-repapi.cpp~82b9b00c67cfdcf7: Delete: storage/ndb/src/old_files/rep/repapi/repapi.cpp BitKeeper/deleted/.del-repapi.h~6f8cf6b53a86a5ae: Delete: storage/ndb/src/old_files/rep/repapi/repapi.h BitKeeper/deleted/.del-Interval.cpp~3d079ca9cc21124d: Delete: storage/ndb/src/old_files/rep/state/Interval.cpp BitKeeper/deleted/.del-Interval.hpp~85aa46fc419bb109: Delete: storage/ndb/src/old_files/rep/state/Interval.hpp BitKeeper/deleted/.del-Makefile~6a9cedaeedcc4650: Delete: storage/ndb/src/old_files/rep/state/Makefile BitKeeper/deleted/.del-RepState.cpp~3d60b0a46e9477c1: Delete: storage/ndb/src/old_files/rep/state/RepState.cpp BitKeeper/deleted/.del-Makefile~e33e587a7947ac36: Delete: storage/ndb/src/old_files/rep/state/testInterval/Makefile BitKeeper/deleted/.del-RepState.hpp~94d7c472c8a7367: Delete: storage/ndb/src/old_files/rep/state/RepState.hpp BitKeeper/deleted/.del-RepStateEvent.cpp~f51d7eb7b7aca0b: Delete: storage/ndb/src/old_files/rep/state/RepStateEvent.cpp BitKeeper/deleted/.del-RepStateRequests.cpp~393882166df6929: Delete: storage/ndb/src/old_files/rep/state/RepStateRequests.cpp BitKeeper/deleted/.del-Makefile~f5a6d9415d7e0977: Delete: storage/ndb/src/old_files/rep/state/testRepState/Makefile BitKeeper/deleted/.del-testInterval.cpp~993f4118f616e80: Delete: storage/ndb/src/old_files/rep/state/testInterval/testInterval.cpp BitKeeper/deleted/.del-testRequestor.cpp~4a943fae5be63c79: Delete: storage/ndb/src/old_files/rep/state/testRepState/testRequestor.cpp BitKeeper/deleted/.del-testRequestor.hpp~583208c83ff5b554: Delete: storage/ndb/src/old_files/rep/state/testRepState/testRequestor.hpp BitKeeper/deleted/.del-GCIBuffer.cpp~6e8c6f38ab63d1d6: Delete: storage/ndb/src/old_files/rep/storage/GCIBuffer.cpp BitKeeper/deleted/.del-GCIBuffer.hpp~703e2016a7ec616f: Delete: storage/ndb/src/old_files/rep/storage/GCIBuffer.hpp BitKeeper/deleted/.del-GCIContainer.cpp~9c53acd16fc5ac74: Delete: storage/ndb/src/old_files/rep/storage/GCIContainer.cpp BitKeeper/deleted/.del-GCIContainer.hpp~ac28cea9114659fd: Delete: storage/ndb/src/old_files/rep/storage/GCIContainer.hpp BitKeeper/deleted/.del-GCIContainerPS.cpp~116168903a2c617a: Delete: storage/ndb/src/old_files/rep/storage/GCIContainerPS.cpp BitKeeper/deleted/.del-GCIContainerPS.hpp~9a801ffe939e192e: Delete: storage/ndb/src/old_files/rep/storage/GCIContainerPS.hpp BitKeeper/deleted/.del-GCIPage.cpp~42fa918fbf36828a: Delete: storage/ndb/src/old_files/rep/storage/GCIPage.cpp BitKeeper/deleted/.del-GCIPage.hpp~4197e2278326515e: Delete: storage/ndb/src/old_files/rep/storage/GCIPage.hpp BitKeeper/deleted/.del-LogRecord.hpp~11644fe7c5f5d36: Delete: storage/ndb/src/old_files/rep/storage/LogRecord.hpp BitKeeper/deleted/.del-Makefile~a955d34726662aba: Delete: storage/ndb/src/old_files/rep/storage/Makefile BitKeeper/deleted/.del-NodeConnectInfo.hpp~35a7682fd9dba464: Delete: storage/ndb/src/old_files/rep/storage/NodeConnectInfo.hpp BitKeeper/deleted/.del-NodeGroup.cpp~adebbefb11cd1670: Delete: storage/ndb/src/old_files/rep/storage/NodeGroup.cpp BitKeeper/deleted/.del-NodeGroup.hpp~3fcddc2da5d10e45: Delete: storage/ndb/src/old_files/rep/storage/NodeGroup.hpp BitKeeper/deleted/.del-Makefile~6b43df78ea480db1: Delete: storage/ndb/src/old_files/rep/transfer/Makefile BitKeeper/deleted/.del-NodeGroupInfo.cpp~b1130e3c42777658: Delete: storage/ndb/src/old_files/rep/storage/NodeGroupInfo.cpp BitKeeper/deleted/.del-NodeGroupInfo.hpp~7fd3b74f4b59a503: Delete: storage/ndb/src/old_files/rep/storage/NodeGroupInfo.hpp BitKeeper/deleted/.del-TransPS.cpp~7a88ca746987ac10: Delete: storage/ndb/src/old_files/rep/transfer/TransPS.cpp BitKeeper/deleted/.del-TransPS.hpp~846b26eaa80632a1: Delete: storage/ndb/src/old_files/rep/transfer/TransPS.hpp BitKeeper/deleted/.del-TransSS.cpp~8f12a062b240eecf: Delete: storage/ndb/src/old_files/rep/transfer/TransSS.cpp BitKeeper/deleted/.del-TransSS.hpp~7718b5e4ce9a4007: Delete: storage/ndb/src/old_files/rep/transfer/TransSS.hpp BitKeeper/deleted/.del-TransSSSubscriptions.cpp~6bc55e474f33e023: Delete: storage/ndb/src/old_files/rep/transfer/TransSSSubscriptions.cpp BitKeeper/deleted/.del-Makefile~4cef97177c0cd8d1: Delete: storage/ndb/test/ndbapi/old_dirs/acid2/Makefile BitKeeper/deleted/.del-Makefile~5823323f9308952b: Delete: storage/ndb/test/ndbapi/old_dirs/acid/Makefile BitKeeper/deleted/.del-Makefile~53e91df162e177a4: Delete: storage/ndb/test/ndbapi/old_dirs/bulk_copy/Makefile BitKeeper/deleted/.del-Makefile~d86129c4e794eaaf: Delete: storage/ndb/test/ndbapi/old_dirs/basicAsynch/Makefile BitKeeper/deleted/.del-TraceNdbApi.hpp~7a7f0ae5b70358bc: Delete: storage/ndb/test/ndbapi/old_dirs/acid2/TraceNdbApi.hpp BitKeeper/deleted/.del-VerifyNdbApi.hpp~f417f78f7cd05935: Delete: storage/ndb/test/ndbapi/old_dirs/acid2/VerifyNdbApi.hpp BitKeeper/deleted/.del-Makefile~15b0005e7dc1fbf8: Delete: storage/ndb/test/ndbapi/old_dirs/flexAsynch/Makefile BitKeeper/deleted/.del-Makefile~1bcf05f0a26d7d6f: Delete: storage/ndb/test/ndbapi/old_dirs/create_tab/Makefile BitKeeper/deleted/.del-Makefile~8ede26305d647424: Delete: storage/ndb/test/ndbapi/old_dirs/create_all_tabs/Makefile BitKeeper/deleted/.del-Makefile~e4f93944b8c44f09: Delete: storage/ndb/test/ndbapi/old_dirs/drop_all_tabs/Makefile BitKeeper/deleted/.del-Makefile.am~ae6c03d81bf83c09: Delete: storage/ndb/test/ndbapi/old_dirs/flexBench/Makefile.am BitKeeper/deleted/.del-Makefile~99efd87dd2a67e6: Delete: storage/ndb/test/ndbapi/old_dirs/flexHammer/Makefile BitKeeper/deleted/.del-README~d85a7f1125dc7a50: Delete: storage/ndb/test/ndbapi/old_dirs/flexHammer/README BitKeeper/deleted/.del-ndbplot.pl~ef4de5b461b880c1: Delete: storage/ndb/test/ndbapi/old_dirs/flexBench/ndbplot.pl BitKeeper/deleted/.del-Makefile~c05a674b968916ec: Delete: storage/ndb/test/ndbapi/old_dirs/flexTT/Makefile BitKeeper/deleted/.del-Makefile~d36727b854d37c9: Delete: storage/ndb/test/ndbapi/old_dirs/flexScan/Makefile BitKeeper/deleted/.del-README~a6f5f72344539aae: Delete: storage/ndb/test/ndbapi/old_dirs/flexScan/README BitKeeper/deleted/.del-Makefile~d254d59f274b1d3: Delete: storage/ndb/test/ndbapi/old_dirs/flex_bench_mysql/Makefile BitKeeper/deleted/.del-Makefile~d280c4556dcab9cd: Delete: storage/ndb/test/ndbapi/old_dirs/flexTimedAsynch/Makefile BitKeeper/deleted/.del-Makefile~7cd666ff39dc1c5d: Delete: storage/ndb/test/ndbapi/old_dirs/indexTest2/Makefile BitKeeper/deleted/.del-Makefile~837866d85a01b2c: Delete: storage/ndb/test/ndbapi/old_dirs/indexTest/Makefile BitKeeper/deleted/.del-Makefile~b384a346d7cc0f3c: Delete: storage/ndb/test/ndbapi/old_dirs/interpreterInTup/Makefile BitKeeper/deleted/.del-Makefile~b77f2b2aa6db29a7: Delete: storage/ndb/test/ndbapi/old_dirs/lmc-bench/Makefile BitKeeper/deleted/.del-Makefile~607887f555e1a07f: Delete: storage/ndb/test/ndbapi/old_dirs/lmc-bench/async-src/Makefile BitKeeper/deleted/.del-Makefile~fe3f7192bcd1e342: Delete: storage/ndb/test/ndbapi/old_dirs/lmc-bench/async-src/generator/Makefile BitKeeper/deleted/.del-dbGenerator.h~63f1aeb98260bcb7: Delete: storage/ndb/test/ndbapi/old_dirs/lmc-bench/async-src/include/dbGenerator.h BitKeeper/deleted/.del-testData.h~898b71d7c639319e: Delete: storage/ndb/test/ndbapi/old_dirs/lmc-bench/async-src/include/testData.h BitKeeper/deleted/.del-Makefile~16dd9625cf816bed: Delete: storage/ndb/test/ndbapi/old_dirs/lmc-bench/async-src/user/Makefile BitKeeper/deleted/.del-macros.h~742871fab0681964: Delete: storage/ndb/test/ndbapi/old_dirs/lmc-bench/async-src/user/macros.h BitKeeper/deleted/.del-ndb_error.hpp~45a2fef922beae3: Delete: storage/ndb/test/ndbapi/old_dirs/lmc-bench/async-src/user/ndb_error.hpp BitKeeper/deleted/.del-userInterface.h~49139f029bbdaabc: Delete: storage/ndb/test/ndbapi/old_dirs/lmc-bench/async-src/include/userInterface.h BitKeeper/deleted/.del-.empty~9401b7f68791202e: Delete: storage/ndb/test/ndbapi/old_dirs/lmc-bench/lib/.empty BitKeeper/deleted/.del-.empty~f804b62cd167f0b3: Delete: storage/ndb/test/ndbapi/old_dirs/lmc-bench/bin/.empty BitKeeper/deleted/.del-ndb_schema.hpp~de9c21185d6bfe4e: Delete: storage/ndb/test/ndbapi/old_dirs/lmc-bench/include/ndb_schema.hpp BitKeeper/deleted/.del-testDefinitions.h~f18a4553579a3725: Delete: storage/ndb/test/ndbapi/old_dirs/lmc-bench/include/testDefinitions.h BitKeeper/deleted/.del-Makefile~28e0b82e1322e47: Delete: storage/ndb/test/ndbapi/old_dirs/lmc-bench/script/Makefile BitKeeper/deleted/.del-async-lmc-bench-l-p10.sh~8f06283d361eec9e: Delete: storage/ndb/test/ndbapi/old_dirs/lmc-bench/script/async-lmc-bench-l-p10.sh BitKeeper/deleted/.del-async-lmc-bench-l.sh~9b204c8488dfdb86: Delete: storage/ndb/test/ndbapi/old_dirs/lmc-bench/script/async-lmc-bench-l.sh BitKeeper/deleted/.del-async-lmc-bench-p10.sh~45cfc4a130b43f6a: Delete: storage/ndb/test/ndbapi/old_dirs/lmc-bench/script/async-lmc-bench-p10.sh BitKeeper/deleted/.del-Makefile~a3e9f0384cf8455d: Delete: storage/ndb/test/ndbapi/old_dirs/lmc-bench/src/Makefile BitKeeper/deleted/.del-README~3c1d85ad9efb4a23: Delete: storage/ndb/test/ndbapi/old_dirs/lmc-bench/src/README BitKeeper/deleted/.del-async-lmc-bench.sh~40ca1b63e69d2bdd: Delete: storage/ndb/test/ndbapi/old_dirs/lmc-bench/script/async-lmc-bench.sh BitKeeper/deleted/.del-makevars.linux~9a7c7e0df35184fa: Delete: storage/ndb/test/ndbapi/old_dirs/lmc-bench/src/makevars.linux BitKeeper/deleted/.del-Makefile~e5ecf4cfa15f5316: Delete: storage/ndb/test/ndbapi/old_dirs/lmc-bench/src/generator/Makefile BitKeeper/deleted/.del-dbGenerator.c~7509c19f70cad0bf: Delete: storage/ndb/test/ndbapi/old_dirs/lmc-bench/src/generator/dbGenerator.c BitKeeper/deleted/.del-dbGenerator.h~e1aaa6725999d458: Delete: storage/ndb/test/ndbapi/old_dirs/lmc-bench/src/generator/dbGenerator.h BitKeeper/deleted/.del-mainGenerator.c~2d1c8016f72b2517: Delete: storage/ndb/test/ndbapi/old_dirs/lmc-bench/src/generator/mainGenerator.c BitKeeper/deleted/.del-makevars.sparc~42a7f929ba44ea5: Delete: storage/ndb/test/ndbapi/old_dirs/lmc-bench/src/makevars.sparc BitKeeper/deleted/.del-Makefile~c3c3d76f731f62: Delete: storage/ndb/test/ndbapi/old_dirs/lmc-bench/src/populator/Makefile BitKeeper/deleted/.del-testData.h~696038ea2623a90b: Delete: storage/ndb/test/ndbapi/old_dirs/lmc-bench/src/include/testData.h BitKeeper/deleted/.del-userInterface.h~1f76ad2f28b283fd: Delete: storage/ndb/test/ndbapi/old_dirs/lmc-bench/src/include/userInterface.h BitKeeper/deleted/.del-Makefile~548d94b487507bbf: Delete: storage/ndb/test/ndbapi/old_dirs/lmc-bench/src/user/Makefile BitKeeper/deleted/.del-dbPopulate.c~5dcff1c99783d83b: Delete: storage/ndb/test/ndbapi/old_dirs/lmc-bench/src/populator/dbPopulate.c BitKeeper/deleted/.del-dbPopulate.h~229a894b59d4da73: Delete: storage/ndb/test/ndbapi/old_dirs/lmc-bench/src/populator/dbPopulate.h BitKeeper/deleted/.del-mainPopulate.c~37def9a44980b8ec: Delete: storage/ndb/test/ndbapi/old_dirs/lmc-bench/src/populator/mainPopulate.c BitKeeper/deleted/.del-localDbPrepare.c~33a2c46afc8fac9a: Delete: storage/ndb/test/ndbapi/old_dirs/lmc-bench/src/user/localDbPrepare.c BitKeeper/deleted/.del-macros.h~58097d584e29b5df: Delete: storage/ndb/test/ndbapi/old_dirs/lmc-bench/src/user/macros.h BitKeeper/deleted/.del-ndb_error.hpp~24468bb7f20a0b41: Delete: storage/ndb/test/ndbapi/old_dirs/lmc-bench/src/user/ndb_error.hpp BitKeeper/deleted/.del-userHandle.h~ec22dc7a7ed2f81b: Delete: storage/ndb/test/ndbapi/old_dirs/lmc-bench/src/user/userHandle.h BitKeeper/deleted/.del-Makefile~b6d0cd4d8c9d339b: Delete: storage/ndb/test/ndbapi/old_dirs/lmc-bench/src/user/old/Makefile BitKeeper/deleted/.del-userHandle.h~3275bb415e1ca2c2: Delete: storage/ndb/test/ndbapi/old_dirs/lmc-bench/src/user/old/userHandle.h BitKeeper/deleted/.del-userInterface.cpp~82ee612ab14b3d48: Delete: storage/ndb/test/ndbapi/old_dirs/lmc-bench/src/user/userInterface.cpp BitKeeper/deleted/.del-userTransaction.c~438012ecc761b776: Delete: storage/ndb/test/ndbapi/old_dirs/lmc-bench/src/user/userTransaction.c BitKeeper/deleted/.del-Makefile~6a739ef75a821406: Delete: storage/ndb/test/ndbapi/old_dirs/restarter2/Makefile BitKeeper/deleted/.del-Makefile~c4a8d15a64d73ee8: Delete: storage/ndb/test/ndbapi/old_dirs/restarter/Makefile BitKeeper/deleted/.del-userInterface.c~92a20032f7d1e91: Delete: storage/ndb/test/ndbapi/old_dirs/lmc-bench/src/user/old/userInterface.c BitKeeper/deleted/.del-userTransaction.c~f50661b4f54b0bdd: Delete: storage/ndb/test/ndbapi/old_dirs/lmc-bench/src/user/old/userTransaction.c BitKeeper/deleted/.del-Makefile~23f3806c8505ea8f: Delete: storage/ndb/test/ndbapi/old_dirs/ronja/initronja/Makefile BitKeeper/deleted/.del-Makefile~2fdd0e2bfef9eab7: Delete: storage/ndb/test/ndbapi/old_dirs/ronja/benchronja/Makefile BitKeeper/deleted/.del-Makefile~d19ef6b3a02430e7: Delete: storage/ndb/test/ndbapi/old_dirs/restarts/Makefile BitKeeper/deleted/.del-Makefile~edc1824919a8e593: Delete: storage/ndb/test/ndbapi/old_dirs/ronja/Makefile BitKeeper/deleted/.del-Makefile~7246dc45283fec4f: Delete: storage/ndb/test/ndbapi/old_dirs/testBasic/Makefile BitKeeper/deleted/.del-Makefile~8f8a72ead5c0dcbe: Delete: storage/ndb/test/ndbapi/old_dirs/testBackup/Makefile BitKeeper/deleted/.del-Makefile~a8998c89d7ad17d0: Delete: storage/ndb/test/ndbapi/old_dirs/telco/Makefile BitKeeper/deleted/.del-readme~2bb11c8fe8e713de: Delete: storage/ndb/test/ndbapi/old_dirs/telco/readme BitKeeper/deleted/.del-Makefile~11a681d847711b20: Delete: storage/ndb/test/ndbapi/old_dirs/testDataBuffers/Makefile BitKeeper/deleted/.del-Makefile~7b08d94bc77f36b5: Delete: storage/ndb/test/ndbapi/old_dirs/testDict/Makefile BitKeeper/deleted/.del-Makefile~c72222538e5e4e48: Delete: storage/ndb/test/ndbapi/old_dirs/testBlobs/Makefile BitKeeper/deleted/.del-Makefile~13237b5015038e7b: Delete: storage/ndb/test/ndbapi/old_dirs/testGrep/Makefile BitKeeper/deleted/.del-Makefile~1e91adbf308b09: Delete: storage/ndb/test/ndbapi/old_dirs/testGrep/verify/Makefile BitKeeper/deleted/.del-Makefile~348a4f3067115b99: Delete: storage/ndb/test/ndbapi/old_dirs/testIndex/Makefile BitKeeper/deleted/.del-Makefile~4da89995b201a972: Delete: storage/ndb/test/ndbapi/old_dirs/testInterpreter/Makefile BitKeeper/deleted/.del-Makefile~664fcd5e178e659a: Delete: storage/ndb/test/ndbapi/old_dirs/testNodeRestart/Makefile BitKeeper/deleted/.del-Makefile~79ba0e5994952ae9: Delete: storage/ndb/test/ndbapi/old_dirs/testNdbApi/Makefile BitKeeper/deleted/.del-Makefile~b76c5fcf57c53a58: Delete: storage/ndb/test/ndbapi/old_dirs/testOIBasic/Makefile BitKeeper/deleted/.del-Makefile~b90fa88b1071a3f3: Delete: storage/ndb/test/ndbapi/old_dirs/testMgm/Makefile BitKeeper/deleted/.del-Makefile~3a1d081f812432e3: Delete: storage/ndb/test/ndbapi/old_dirs/testRestartGci/Makefile BitKeeper/deleted/.del-Makefile~3e916b320b0dc88: Delete: storage/ndb/test/ndbapi/old_dirs/testOrderedIndex/Makefile BitKeeper/deleted/.del-Makefile~c9fac39964fe2f77: Delete: storage/ndb/test/ndbapi/old_dirs/testOperations/Makefile BitKeeper/deleted/.del-times.txt~76ffa76ca8708af1: Delete: storage/ndb/test/ndbapi/old_dirs/testOIBasic/times.txt BitKeeper/deleted/.del-Makefile~8ec0ddece8d8bd18: Delete: storage/ndb/test/ndbapi/old_dirs/testScanInterpreter/Makefile BitKeeper/deleted/.del-Makefile~b3c2cd57699a958c: Delete: storage/ndb/test/ndbapi/old_dirs/testSystemRestart/Makefile BitKeeper/deleted/.del-Makefile~c6f264b16640c32b: Delete: storage/ndb/test/ndbapi/old_dirs/testScan/Makefile BitKeeper/deleted/.del-Makefile~f5c05697b5c6a926: Delete: storage/ndb/test/ndbapi/old_dirs/testTimeout/Makefile BitKeeper/deleted/.del-Makefile~2e74033e6077aa3a: Delete: storage/ndb/test/ndbapi/old_dirs/testTransactions/Makefile BitKeeper/deleted/.del-Makefile~91dad370d76274be: Delete: storage/ndb/test/ndbapi/old_dirs/vw_test/Makefile BitKeeper/deleted/.del-Makefile~ddc74468722656bb: Delete: storage/ndb/test/ndbapi/old_dirs/test_event/Makefile BitKeeper/deleted/.del-bcd.h~81fbfcc1530534da: Delete: storage/ndb/test/ndbapi/old_dirs/vw_test/bcd.h BitKeeper/deleted/.del-client_start~1ecfaed180a75edd: Delete: storage/ndb/test/ndbapi/old_dirs/vw_test/script/client_start BitKeeper/deleted/.del-utv.h~f64af026b9705ebb: Delete: storage/ndb/test/ndbapi/old_dirs/vw_test/utv.h BitKeeper/deleted/.del-vcdrfunc.h~85803875180684cd: Delete: storage/ndb/test/ndbapi/old_dirs/vw_test/vcdrfunc.h BitKeeper/deleted/.del-Makefile~ae168985806f34e8: Delete: storage/ndb/src/common/portlib/old_dirs/ose/Makefile BitKeeper/deleted/.del-Makefile~b50f189dfbc87d8a: Delete: storage/ndb/src/common/portlib/old_dirs/memtest/munmaptest/Makefile BitKeeper/deleted/.del-Makefile~dcc8c444bf25ce41: Delete: storage/ndb/src/common/portlib/old_dirs/memtest/Makefile BitKeeper/deleted/.del-NdbCondition.c~ee56562abdd718cf: Delete: storage/ndb/src/common/portlib/old_dirs/ose/NdbCondition.c BitKeeper/deleted/.del-NdbConditionOSE.h~455dd2c29c2e6344: Delete: storage/ndb/src/common/portlib/old_dirs/ose/NdbConditionOSE.h BitKeeper/deleted/.del-NdbEnv.c~bb6fe7572d45288a: Delete: storage/ndb/src/common/portlib/old_dirs/ose/NdbEnv.c BitKeeper/deleted/.del-NdbHost.c~cf18d6b3c825180c: Delete: storage/ndb/src/common/portlib/old_dirs/ose/NdbHost.c BitKeeper/deleted/.del-NdbMem.c~6c2b317c1ce230ab: Delete: storage/ndb/src/common/portlib/old_dirs/ose/NdbMem.c BitKeeper/deleted/.del-NdbMem_SoftOse.cpp~9c61e311ec168d44: Delete: storage/ndb/src/common/portlib/old_dirs/ose/NdbMem_SoftOse.cpp BitKeeper/deleted/.del-NdbMutex.c~f4bdd19be08b84ab: Delete: storage/ndb/src/common/portlib/old_dirs/ose/NdbMutex.c BitKeeper/deleted/.del-NdbOut.cpp~8caa99a0d729540c: Delete: storage/ndb/src/common/portlib/old_dirs/ose/NdbOut.cpp BitKeeper/deleted/.del-NdbSleep.c~b88fbc5b140de10d: Delete: storage/ndb/src/common/portlib/old_dirs/ose/NdbSleep.c BitKeeper/deleted/.del-NdbTCP.c~1e9f416992352f6d: Delete: storage/ndb/src/common/portlib/old_dirs/ose/NdbTCP.c BitKeeper/deleted/.del-NdbThread.c~fe71a67b5c3a4724: Delete: storage/ndb/src/common/portlib/old_dirs/ose/NdbThread.c BitKeeper/deleted/.del-NdbTick.c~b76feba2cf1493d1: Delete: storage/ndb/src/common/portlib/old_dirs/ose/NdbTick.c BitKeeper/deleted/.del-Makefile~aa96712c481bc8e: Delete: storage/ndb/src/common/portlib/old_dirs/win32/Makefile BitKeeper/deleted/.del-Makefile~d04b4a185b6e1071: Delete: storage/ndb/src/common/portlib/old_dirs/test/Makefile BitKeeper/deleted/.del-NdbCondition.c~ad83464328ab37af: Delete: storage/ndb/src/common/portlib/old_dirs/win32/NdbCondition.c BitKeeper/deleted/.del-NdbDaemon.c~3b8101f376b28df: Delete: storage/ndb/src/common/portlib/old_dirs/win32/NdbDaemon.c BitKeeper/deleted/.del-NdbEnv.c~207f9ce9754c9e8a: Delete: storage/ndb/src/common/portlib/old_dirs/win32/NdbEnv.c BitKeeper/deleted/.del-NdbHost.c~2c29816c77396d7b: Delete: storage/ndb/src/common/portlib/old_dirs/win32/NdbHost.c BitKeeper/deleted/.del-NdbMem.c~6285b159985d46da: Delete: storage/ndb/src/common/portlib/old_dirs/win32/NdbMem.c BitKeeper/deleted/.del-NdbMutex.c~768131269bccca10: Delete: storage/ndb/src/common/portlib/old_dirs/win32/NdbMutex.c BitKeeper/deleted/.del-NdbSleep.c~b643ea3e7103eb62: Delete: storage/ndb/src/common/portlib/old_dirs/win32/NdbSleep.c BitKeeper/deleted/.del-NdbTCP.c~b09cdcbef3ea2c57: Delete: storage/ndb/src/common/portlib/old_dirs/win32/NdbTCP.c BitKeeper/deleted/.del-NdbThread.c~2fe1fa5f47801772: Delete: storage/ndb/src/common/portlib/old_dirs/win32/NdbThread.c BitKeeper/deleted/.del-NdbTick.c~aa6385567216509d: Delete: storage/ndb/src/common/portlib/old_dirs/win32/NdbTick.c BitKeeper/deleted/.del-Makefile~62207a82b90e653: Delete: storage/ndb/test/tools/old_dirs/hugoCalculator/Makefile BitKeeper/deleted/.del-Makefile~54e6a2262bbe162a: Delete: storage/ndb/test/tools/old_dirs/hugoLockRecords/Makefile BitKeeper/deleted/.del-Makefile~79e81dfed9112c7: Delete: storage/ndb/test/tools/old_dirs/hugoLoad/Makefile BitKeeper/deleted/.del-Makefile~c2b94348137b633a: Delete: storage/ndb/test/tools/old_dirs/hugoPkDelete/Makefile BitKeeper/deleted/.del-Makefile~f90065821a932b3f: Delete: storage/ndb/test/tools/old_dirs/hugoFill/Makefile BitKeeper/deleted/.del-Makefile~3ae1e42a4d7b1d6a: Delete: storage/ndb/test/tools/old_dirs/hugoPkRead/Makefile BitKeeper/deleted/.del-Makefile~89557cc224193d4: Delete: storage/ndb/test/tools/old_dirs/hugoPkReadRecord/Makefile BitKeeper/deleted/.del-Makefile~a6a5bd72a2311773: Delete: storage/ndb/test/tools/old_dirs/hugoScanRead/Makefile BitKeeper/deleted/.del-Makefile~e918384f46b2aef0: Delete: storage/ndb/test/tools/old_dirs/hugoPkUpdate/Makefile BitKeeper/deleted/.del-Makefile~2a7bcc03f802d4f: Delete: storage/ndb/test/tools/old_dirs/hugoScanUpdate/Makefile BitKeeper/deleted/.del-Makefile~2f05dedf982dcd9: Delete: storage/ndb/test/tools/old_dirs/transproxy/Makefile BitKeeper/deleted/.del-Makefile~b9e514baf06145d5: Delete: storage/ndb/test/tools/old_dirs/restart/Makefile BitKeeper/deleted/.del-Makefile~f1d6329f42d0922d: Delete: storage/ndb/test/tools/old_dirs/verify_index/Makefile BitKeeper/deleted/.del-waiter.cpp~b188e4bfddf2cf98: Delete: storage/ndb/test/tools/old_dirs/waiter/waiter.cpp BitKeeper/deleted/.del-Makefile~65110e0a5cb381: Delete: storage/ndb/tools/old_dirs/copy_tab/Makefile BitKeeper/deleted/.del-Makefile~6dbecfdfc2878bb3: Delete: storage/ndb/tools/old_dirs/cpcc/Makefile BitKeeper/deleted/.del-Makefile~77a4d0f4c11f13b5: Delete: storage/ndb/tools/old_dirs/create_index/Makefile BitKeeper/deleted/.del-Makefile~57f187037bf9e65d: Delete: storage/ndb/tools/old_dirs/desc/Makefile BitKeeper/deleted/.del-Makefile~b25e897a378dd139: Delete: storage/ndb/tools/old_dirs/delete_all/Makefile BitKeeper/deleted/.del-Makefile~1b4547a47a5607: Delete: storage/ndb/tools/old_dirs/drop_index/Makefile BitKeeper/deleted/.del-Makefile~62140e0b68eb516c: Delete: storage/ndb/tools/old_dirs/drop_tab/Makefile BitKeeper/deleted/.del-Makefile~b95bfed632918157: Delete: storage/ndb/tools/old_dirs/list_tables/Makefile BitKeeper/deleted/.del-Makefile.PL~81be90388548652f: Delete: storage/ndb/tools/old_dirs/ndbnet/Makefile.PL BitKeeper/deleted/.del-ndbnet.pl~8f8f1b18f0458269: Delete: storage/ndb/tools/old_dirs/ndbnet/ndbnet.pl BitKeeper/deleted/.del-ndbnetd.pl~e44f1cfe7e8bbe14: Delete: storage/ndb/tools/old_dirs/ndbnet/ndbnetd.pl BitKeeper/deleted/.del-Base.pm~50a6f0d38fa1a57c: Delete: storage/ndb/tools/old_dirs/ndbnet/lib/NDB/Net/Base.pm BitKeeper/deleted/.del-ndbrun~5db549d7436ac81b: Delete: storage/ndb/tools/old_dirs/ndbnet/ndbrun BitKeeper/deleted/.del-Client.pm~45adb527c5cfdaf6: Delete: storage/ndb/tools/old_dirs/ndbnet/lib/NDB/Net/Client.pm BitKeeper/deleted/.del-Command.pm~a20dff1bfd06ea7a: Delete: storage/ndb/tools/old_dirs/ndbnet/lib/NDB/Net/Command.pm BitKeeper/deleted/.del-Config.pm~24456d4beba19604: Delete: storage/ndb/tools/old_dirs/ndbnet/lib/NDB/Net/Config.pm BitKeeper/deleted/.del-Database.pm~cc02e455b02c557: Delete: storage/ndb/tools/old_dirs/ndbnet/lib/NDB/Net/Database.pm BitKeeper/deleted/.del-Env.pm~ffeca4ab253818c3: Delete: storage/ndb/tools/old_dirs/ndbnet/lib/NDB/Net/Env.pm BitKeeper/deleted/.del-Node.pm~276106bf4000fe2b: Delete: storage/ndb/tools/old_dirs/ndbnet/lib/NDB/Net/Node.pm BitKeeper/deleted/.del-NodeApi.pm~3abf1d7bc947d3d0: Delete: storage/ndb/tools/old_dirs/ndbnet/lib/NDB/Net/NodeApi.pm BitKeeper/deleted/.del-NodeDb.pm~9e3055381da679ce: Delete: storage/ndb/tools/old_dirs/ndbnet/lib/NDB/Net/NodeDb.pm BitKeeper/deleted/.del-NodeMgmt.pm~5123fbffcfce73cb: Delete: storage/ndb/tools/old_dirs/ndbnet/lib/NDB/Net/NodeMgmt.pm BitKeeper/deleted/.del-Server.pm~70208c964371fd4d: Delete: storage/ndb/tools/old_dirs/ndbnet/lib/NDB/Net/Server.pm BitKeeper/deleted/.del-ServerINET.pm~fc72d28fedd17795: Delete: storage/ndb/tools/old_dirs/ndbnet/lib/NDB/Net/ServerINET.pm BitKeeper/deleted/.del-ServerUNIX.pm~ad3e25435fceb8d0: Delete: storage/ndb/tools/old_dirs/ndbnet/lib/NDB/Net/ServerUNIX.pm BitKeeper/deleted/.del-Base.pm~dd382c9eec2c38b1: Delete: storage/ndb/tools/old_dirs/ndbnet/lib/NDB/Run/Base.pm BitKeeper/deleted/.del-Database.pm~ec533cd5dd6a54a2: Delete: storage/ndb/tools/old_dirs/ndbnet/lib/NDB/Run/Database.pm BitKeeper/deleted/.del-Env.pm~a343841fae6d0514: Delete: storage/ndb/tools/old_dirs/ndbnet/lib/NDB/Run/Env.pm BitKeeper/deleted/.del-Net.pm~425c84165071d5f6: Delete: storage/ndb/tools/old_dirs/ndbnet/lib/NDB/Net.pm BitKeeper/deleted/.del-Node.pm~339139ded5fcf795: Delete: storage/ndb/tools/old_dirs/ndbnet/lib/NDB/Run/Node.pm BitKeeper/deleted/.del-Run.pm~9b414f2b4b76a4da: Delete: storage/ndb/tools/old_dirs/ndbnet/lib/NDB/Run.pm BitKeeper/deleted/.del-Base.pm~f39906f304e8a49: Delete: storage/ndb/tools/old_dirs/ndbnet/lib/NDB/Util/Base.pm BitKeeper/deleted/.del-Util.pm~9be64f1195ec502d: Delete: storage/ndb/tools/old_dirs/ndbnet/lib/NDB/Util.pm BitKeeper/deleted/.del-Dir.pm~4cbe8dd8c57149a7: Delete: storage/ndb/tools/old_dirs/ndbnet/lib/NDB/Util/Dir.pm BitKeeper/deleted/.del-Event.pm~f445c1c094f57cf: Delete: storage/ndb/tools/old_dirs/ndbnet/lib/NDB/Util/Event.pm BitKeeper/deleted/.del-File.pm~48da8e977f39bf7: Delete: storage/ndb/tools/old_dirs/ndbnet/lib/NDB/Util/File.pm BitKeeper/deleted/.del-IO.pm~6c6a63ce63fe2ee5: Delete: storage/ndb/tools/old_dirs/ndbnet/lib/NDB/Util/IO.pm BitKeeper/deleted/.del-Lock.pm~366e56786358b3d8: Delete: storage/ndb/tools/old_dirs/ndbnet/lib/NDB/Util/Lock.pm BitKeeper/deleted/.del-Log.pm~e0da9468a6f9213a: Delete: storage/ndb/tools/old_dirs/ndbnet/lib/NDB/Util/Log.pm BitKeeper/deleted/.del-Socket.pm~371ccd6c5a818fa0: Delete: storage/ndb/tools/old_dirs/ndbnet/lib/NDB/Util/Socket.pm BitKeeper/deleted/.del-SocketINET.pm~db8a45b1360b69f2: Delete: storage/ndb/tools/old_dirs/ndbnet/lib/NDB/Util/SocketINET.pm BitKeeper/deleted/.del-SocketUNIX.pm~9ffab2ada7f61530: Delete: storage/ndb/tools/old_dirs/ndbnet/lib/NDB/Util/SocketUNIX.pm BitKeeper/deleted/.del-Makefile~b15469c2fbde2dec: Delete: storage/ndb/tools/old_dirs/ndbsql/Makefile BitKeeper/deleted/.del-Makefile~3d1cd223b42a8fa0: Delete: storage/ndb/tools/old_dirs/select_count/Makefile BitKeeper/deleted/.del-Makefile~62f516a16a0cf773: Delete: storage/ndb/tools/old_dirs/select_all/Makefile BitKeeper/deleted/.del-CounterViewer.java~e83264ff6a5be97: Delete: storage/ndb/tools/old_dirs/src/counterviewer/CounterViewer.java storage/ndb/Makefile.am: Remove reference to old_files directory
This commit is contained in:
@@ -7,7 +7,6 @@ include $(top_srcdir)/storage/ndb/config/common.mk.am
|
||||
|
||||
dist-hook:
|
||||
-rm -rf `find $(distdir) -type d -name SCCS`
|
||||
-rm -rf `find $(distdir) -type d -name old_files`
|
||||
-rm -rf `find $(distdir)/ndbapi-examples -name '*.o'`
|
||||
list='$(SUBDIRS)'; for subdir in $$list; do \
|
||||
if test "$$subdir" != "." -a "$$subdir" != "include"; then \
|
||||
|
@@ -1,12 +0,0 @@
|
||||
CC=gcc
|
||||
LD=$(CC)
|
||||
SOURCES=memtest.c
|
||||
OUTPUT=memtest
|
||||
all:
|
||||
$(CC) $(SOURCES) -o $(OUTPUT)
|
||||
|
||||
debug:
|
||||
$(CC) -g $(SOURCES) -o $(OUTPUT)
|
||||
|
||||
clean: rm -rf *.o
|
||||
rm -rf core*
|
@@ -1,14 +0,0 @@
|
||||
include .defs.mk
|
||||
|
||||
TYPE := ndbapitest
|
||||
BIN_TARGET := munmaptest
|
||||
|
||||
|
||||
SOURCES = munmaptest.cpp
|
||||
|
||||
include $(NDB_TOP)/Epilogue.mk
|
||||
|
||||
|
||||
|
||||
|
||||
|
@@ -1,31 +0,0 @@
|
||||
include .defs.mk
|
||||
|
||||
TYPE :=
|
||||
|
||||
PIC_ARCHIVE := Y
|
||||
ARCHIVE_TARGET := portlib
|
||||
|
||||
SOURCES = NdbOut.cpp
|
||||
|
||||
SOURCES.c = NdbCondition.c \
|
||||
NdbMutex.c \
|
||||
NdbSleep.c \
|
||||
NdbTick.c \
|
||||
NdbEnv.c \
|
||||
NdbThread.c \
|
||||
NdbHost.c \
|
||||
NdbTCP.c
|
||||
|
||||
ifeq ($(NDB_OS), SOFTOSE)
|
||||
SOURCES += NdbMem_SoftOse.cpp
|
||||
else
|
||||
SOURCES.c += NdbMem.c
|
||||
endif
|
||||
|
||||
include $(NDB_TOP)/Epilogue.mk
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
@@ -1,243 +0,0 @@
|
||||
/* Copyright (C) 2003 MySQL AB
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||
|
||||
|
||||
#include "NdbCondition.h"
|
||||
#include <pthread.h>
|
||||
#include <sys/types.h>
|
||||
#include <malloc.h>
|
||||
|
||||
#include <NdbMutex.h>
|
||||
|
||||
#include "NdbConditionOSE.h"
|
||||
struct NdbCondition
|
||||
{
|
||||
PROCESS condserv_pid;
|
||||
};
|
||||
|
||||
|
||||
OS_PROCESS(ndbcond_serv){
|
||||
|
||||
union SIGNAL* sig;
|
||||
union SIGNAL* sig2;
|
||||
|
||||
static const SIGSELECT sel_signal[] = {2, NDBCOND_SIGNAL, NDBCOND_BROADCAST};
|
||||
static const SIGSELECT sel_cond[] = {2, NDBCOND_WAIT, NDBCOND_WAITTIMEOUT};
|
||||
|
||||
for(;;){
|
||||
/* Receive condition wait signal */
|
||||
sig = receive((SIGSELECT*)sel_cond);
|
||||
if (sig != NIL){
|
||||
switch (sig->sigNo){
|
||||
|
||||
case NDBCOND_WAIT:
|
||||
/* Wait for a SIGNAL or BROADCAST from anyone */
|
||||
sig2 = receive((SIGSELECT*)sel_signal);
|
||||
if (sig2 != NIL){
|
||||
switch(sig2->sigNo){
|
||||
|
||||
case NDBCOND_SIGNAL:
|
||||
((struct NdbCondWait*)sig)->status = NDBCOND_SIGNALED;
|
||||
/* Send signal back to the one waiting for this condition */
|
||||
send(&sig, sender(&sig));
|
||||
break;
|
||||
case NDBCOND_BROADCAST:
|
||||
/* Not handled yet */
|
||||
assert(1==0);
|
||||
break;
|
||||
default:
|
||||
assert(1==0);
|
||||
break;
|
||||
}
|
||||
free_buf(&sig2);
|
||||
}
|
||||
break;
|
||||
|
||||
case NDBCOND_WAITTIMEOUT:
|
||||
/* Wait for a SIGNAL or BROADCAST from anyone */
|
||||
sig2 = receive_w_tmo(((struct NdbCondWaitTimeout*)sig)->timeout, (SIGSELECT*)sel_signal);
|
||||
if (sig2 != NIL){
|
||||
switch(sig2->sigNo){
|
||||
|
||||
case NDBCOND_SIGNAL:
|
||||
((struct NdbCondWaitTimeout*)sig)->status = NDBCOND_SIGNALED;
|
||||
/* Send signal back to the one waiting for this condition */
|
||||
send(&sig, sender(&sig));
|
||||
break;
|
||||
case NDBCOND_BROADCAST:
|
||||
/* Not handled yet */
|
||||
assert(1==0);
|
||||
break;
|
||||
default:
|
||||
assert(1==0);
|
||||
break;
|
||||
}
|
||||
free_buf(&sig2);
|
||||
}else{
|
||||
((struct NdbCondWaitTimeout*)sig)->status = NDBCOND_TIMEOUT;
|
||||
send(&sig, sender(&sig));
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
assert(1==0);
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
struct NdbCondition*
|
||||
NdbCondition_Create(void)
|
||||
{
|
||||
struct NdbCondition* tmpCond;
|
||||
|
||||
|
||||
tmpCond = (struct NdbCondition*)malloc(sizeof(struct NdbCondition));
|
||||
|
||||
if (tmpCond == NULL)
|
||||
return NULL;
|
||||
|
||||
/**
|
||||
* Start this process with a quite high
|
||||
* priority, we want it to be responsive
|
||||
*/
|
||||
tmpCond->condserv_pid = create_process(OS_PRI_PROC, /* Process type */
|
||||
"ndbcond_serv", /* Name */
|
||||
ndbcond_serv, /* Entry point */
|
||||
2048, /* Stack size */
|
||||
10, /* Priority */
|
||||
0, /* Time slice */
|
||||
get_bid(current_process()), /* Block */
|
||||
NULL, /* Redir table */
|
||||
0,
|
||||
0);
|
||||
|
||||
start(tmpCond->condserv_pid);
|
||||
|
||||
return tmpCond;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
NdbCondition_Wait(struct NdbCondition* p_cond,
|
||||
NdbMutex* p_mutex)
|
||||
{
|
||||
static const SIGSELECT sel_cond[] = {1, NDBCOND_WAIT};
|
||||
union SIGNAL* sig;
|
||||
int result;
|
||||
if (p_cond == NULL || p_mutex == NULL)
|
||||
return 0;
|
||||
|
||||
sig = alloc(sizeof(struct NdbCondWait), NDBCOND_WAIT);
|
||||
send(&sig, p_cond->condserv_pid);
|
||||
|
||||
NdbMutex_Unlock(p_mutex);
|
||||
|
||||
result = 1;
|
||||
while(NIL == (sig = receive_from((OSTIME)-1, (SIGSELECT*)sel_cond, p_cond->condserv_pid)));
|
||||
if (sig != NIL){
|
||||
if (sig->sigNo == NDBCOND_WAIT){
|
||||
/* Condition is signaled */
|
||||
result = 0;
|
||||
}else{
|
||||
assert(1==0);
|
||||
}
|
||||
free_buf(&sig);
|
||||
|
||||
}
|
||||
NdbMutex_Lock(p_mutex);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
NdbCondition_WaitTimeout(struct NdbCondition* p_cond,
|
||||
NdbMutex* p_mutex,
|
||||
int msecs){
|
||||
static const SIGSELECT sel_cond[] = {1, NDBCOND_WAITTIMEOUT};
|
||||
union SIGNAL* sig;
|
||||
int result;
|
||||
if (p_cond == NULL || p_mutex == NULL)
|
||||
return 0;
|
||||
|
||||
sig = alloc(sizeof(struct NdbCondWaitTimeout), NDBCOND_WAITTIMEOUT);
|
||||
((struct NdbCondWaitTimeout*)sig)->timeout = msecs;
|
||||
send(&sig, p_cond->condserv_pid);
|
||||
|
||||
NdbMutex_Unlock(p_mutex);
|
||||
|
||||
result = 1;
|
||||
while(NIL == (sig = receive_from((OSTIME)-1, (SIGSELECT*)sel_cond, p_cond->condserv_pid)));
|
||||
if (sig != NIL){
|
||||
if (sig->sigNo == NDBCOND_WAITTIMEOUT){
|
||||
/* Condition is signaled */
|
||||
result = 0;
|
||||
}else{
|
||||
assert(1==0);
|
||||
}
|
||||
free_buf(&sig);
|
||||
|
||||
}
|
||||
|
||||
NdbMutex_Lock(p_mutex);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
NdbCondition_Signal(struct NdbCondition* p_cond){
|
||||
|
||||
union SIGNAL* sig;
|
||||
if (p_cond == NULL)
|
||||
return 1;
|
||||
|
||||
sig = alloc(sizeof(struct NdbCondSignal), NDBCOND_SIGNAL);
|
||||
send(&sig, p_cond->condserv_pid);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int NdbCondition_Broadcast(struct NdbCondition* p_cond)
|
||||
{
|
||||
union SIGNAL* sig;
|
||||
if (p_cond == NULL)
|
||||
return 1;
|
||||
|
||||
sig = alloc(sizeof(struct NdbCondBroadcast), NDBCOND_BROADCAST);
|
||||
send(&sig, p_cond->condserv_pid);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int NdbCondition_Destroy(struct NdbCondition* p_cond)
|
||||
{
|
||||
if (p_cond == NULL)
|
||||
return 1;
|
||||
|
||||
kill_proc(p_cond->condserv_pid);
|
||||
free(p_cond);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@@ -1,103 +0,0 @@
|
||||
/* Copyright (C) 2003 MySQL AB
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||
|
||||
#ifndef NDB_CONDITIONOSE_H
|
||||
#define NDB_CONDITIONOSE_H
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
#define NDBCOND_SIGBASE 4000
|
||||
|
||||
#define NDBCOND_WAIT (NDBCOND_SIGBASE + 1) /* !-SIGNO(struct NdbCondWait)-! */
|
||||
#define NDBCOND_WAITTIMEOUT (NDBCOND_SIGBASE + 2) /* !-SIGNO(struct NdbCondWaitTimeOut)-! */
|
||||
#define NDBCOND_SIGNAL (NDBCOND_SIGBASE + 3) /* !-SIGNO(struct NdbCondSignal)-! */
|
||||
#define NDBCOND_BROADCAST (NDBCOND_SIGBASE + 4) /* !-SIGNO(struct NdbCondBroadcast)-! */
|
||||
|
||||
|
||||
const char *
|
||||
sigNo2String(SIGSELECT sigNo){
|
||||
switch(sigNo){
|
||||
case NDBCOND_WAIT:
|
||||
return "NDBCOND_WAIT";
|
||||
break;
|
||||
case NDBCOND_WAITTIMEOUT:
|
||||
return "NDBCOND_WAITTIMEOUT";
|
||||
break;
|
||||
case NDBCOND_SIGNAL:
|
||||
return "NDBCOND_SIGNAL";
|
||||
break;
|
||||
case NDBCOND_BROADCAST:
|
||||
return "NDBCOND_BROADCAST";
|
||||
break;
|
||||
}
|
||||
return "UNKNOWN";
|
||||
}
|
||||
|
||||
struct NdbCondWait
|
||||
{
|
||||
SIGSELECT sigNo;
|
||||
int status;
|
||||
};
|
||||
|
||||
/**
|
||||
* Signal received
|
||||
*/
|
||||
#define NDBCOND_SIGNALED 1
|
||||
|
||||
/**
|
||||
* Timeout occured
|
||||
*/
|
||||
#define NDBCOND_TIMEOUT 2
|
||||
|
||||
struct NdbCondWaitTimeout
|
||||
{
|
||||
SIGSELECT sigNo;
|
||||
int timeout;
|
||||
int status;
|
||||
|
||||
};
|
||||
|
||||
struct NdbCondSignal
|
||||
{
|
||||
SIGSELECT sigNo;
|
||||
};
|
||||
|
||||
struct NdbCondBroadcast
|
||||
{
|
||||
SIGSELECT sigNo;
|
||||
};
|
||||
|
||||
|
||||
union SIGNAL
|
||||
{
|
||||
SIGSELECT sigNo;
|
||||
struct NdbCondWait condWait;
|
||||
struct NdbCondWaitTimeout condWaitTimeout;
|
||||
struct NdbCondSignal condSignal;
|
||||
struct NdbCondBroadcast condBroadcast;
|
||||
};
|
||||
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
@@ -1,55 +0,0 @@
|
||||
/* Copyright (C) 2003 MySQL AB
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||
|
||||
|
||||
#include "NdbEnv.h"
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
const char* NdbEnv_GetEnv(const char* name, char * buf, int buflen)
|
||||
{
|
||||
/**
|
||||
* All environment variables are associated with a process
|
||||
* it's important to read env from the correct process
|
||||
* for now read from own process, own block and last the "ose_shell" process.
|
||||
*
|
||||
* TODO! What process should this be read from in the future?
|
||||
*
|
||||
*/
|
||||
PROCESS proc_;
|
||||
char* p = NULL;
|
||||
/* Look in own process */
|
||||
p = get_env(current_process(), (char*)name);
|
||||
if (p == NULL){
|
||||
/* Look in block process */
|
||||
p = get_env(get_bid(current_process()), (char*)name);
|
||||
if (p == NULL){
|
||||
/* Look in ose_shell process */
|
||||
if (hunt("ose_shell", 0, &proc_, NULL)){
|
||||
p = get_env(proc_, (char*)name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (p != NULL){
|
||||
strncpy(buf, p, buflen);
|
||||
buf[buflen-1] = 0;
|
||||
free_buf((union SIGNAL **)&p);
|
||||
p = buf;
|
||||
}
|
||||
return p;
|
||||
}
|
||||
|
@@ -1,55 +0,0 @@
|
||||
/* Copyright (C) 2003 MySQL AB
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||
|
||||
|
||||
#include "NdbHost.h"
|
||||
#include <unistd.h>
|
||||
|
||||
|
||||
#include <inet.sig>
|
||||
#include <string.h>
|
||||
|
||||
union SIGNAL
|
||||
{
|
||||
SIGSELECT sigNo;
|
||||
struct InetIfUp inetIfUp;
|
||||
};
|
||||
|
||||
int NdbHost_GetHostName(char* buf)
|
||||
{
|
||||
#if 0
|
||||
extern PROCESS ose_inet_;
|
||||
union SIGNAL *signal;
|
||||
static const SIGSELECT select_if_up_reply[] = { 1, INET_IF_UP_REPLY };
|
||||
|
||||
signal = alloc(sizeof(struct InetIfUp), INET_IF_UP_REQUEST);
|
||||
strcpy(signal->inetIfUp.ifName, "*");
|
||||
send((union SIGNAL **)&signal, ose_inet_);
|
||||
signal = receive((SIGSELECT *)select_if_up_reply);
|
||||
strcpy(buf, signal->inetIfUp.ifName);
|
||||
free_buf(&signal);
|
||||
return 0;
|
||||
#else
|
||||
return -1;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
int NdbHost_GetProcessId(void)
|
||||
{
|
||||
return current_process();
|
||||
}
|
||||
|
@@ -1,181 +0,0 @@
|
||||
/* Copyright (C) 2003 MySQL AB
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||
|
||||
|
||||
#include "NdbMem.h"
|
||||
|
||||
|
||||
#if defined NDB_OSE
|
||||
#include <ose.h>
|
||||
#include <mms.sig>
|
||||
#include <mms_err.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <NdbOut.hpp>
|
||||
|
||||
// Page size for mp750 is 4096 bytes.
|
||||
#define PAGE_SIZE 4096
|
||||
|
||||
/**
|
||||
* NOTE: To use NdbMem from a OSE system ose_mms has to be defined
|
||||
* as a "Required External Process"(see OSE Kernel User's Guide/R1.1(p. 148)),
|
||||
* like this in osemain.con:
|
||||
* EXT_PROC(ose_mms, ose_mms, 50000)
|
||||
* This will create a global variable ose_mms_ that is used from here.
|
||||
*/
|
||||
|
||||
union SIGNAL
|
||||
{
|
||||
SIGSELECT sigNo;
|
||||
struct MmsAllocateRegionRequest mmsAllocateRegionRequest;
|
||||
struct MmsAllocateRegionReply mmsAllocateRegionReply;
|
||||
struct MmsFreeRegionRequest mmsFreeRegionRequest;
|
||||
struct MmsFreeRegionReply mmsFreeRegionReply;
|
||||
}; /* union SIGNAL */
|
||||
|
||||
extern PROCESS ose_mms_;
|
||||
|
||||
void NdbMem_Create(void)
|
||||
{
|
||||
/* Do nothing */
|
||||
return;
|
||||
}
|
||||
|
||||
void NdbMem_Destroy(void)
|
||||
{
|
||||
/* Do nothing */
|
||||
return;
|
||||
}
|
||||
|
||||
void* NdbMem_Allocate(size_t size)
|
||||
{
|
||||
static SIGSELECT allocate_sig[] = {1,MMS_ALLOCATE_REGION_REPLY};
|
||||
union SIGNAL *sig;
|
||||
U32 allocatedAdress;
|
||||
|
||||
assert(size > 0);
|
||||
|
||||
// Only allowed to allocate multiples of the page size.
|
||||
if(size % PAGE_SIZE != 0) {
|
||||
size += PAGE_SIZE - size%PAGE_SIZE;
|
||||
}
|
||||
|
||||
/* Allocate a new region in the callers memory segment. */
|
||||
sig = alloc(sizeof(struct MmsAllocateRegionRequest),
|
||||
MMS_ALLOCATE_REGION_REQUEST);
|
||||
/* -1: The callers domain is used */
|
||||
sig->mmsAllocateRegionRequest.domain = (MemoryDomain)-1;
|
||||
sig->mmsAllocateRegionRequest.useAddr = False;
|
||||
sig->mmsAllocateRegionRequest.size = size;
|
||||
sig->mmsAllocateRegionRequest.access = SuperRW_UserRW;
|
||||
sig->mmsAllocateRegionRequest.resident = False;
|
||||
sig->mmsAllocateRegionRequest.memory = CodeData;
|
||||
sig->mmsAllocateRegionRequest.cache = CopyBack;
|
||||
strcpy(sig->mmsAllocateRegionRequest.name, "NDB_DATA");
|
||||
send(&sig, ose_mms_);
|
||||
sig = receive(allocate_sig);
|
||||
|
||||
if (sig->mmsAllocateRegionReply.status != MMS_SUCCESS){
|
||||
/* Memory allocation failed, make sure this function returns NULL */
|
||||
allocatedAdress = NULL;
|
||||
}
|
||||
else{
|
||||
allocatedAdress = sig->mmsAllocateRegionReply.address;
|
||||
}
|
||||
free_buf(&sig);
|
||||
return (void*)allocatedAdress;
|
||||
}
|
||||
|
||||
void* NdbMem_AllocateAlign(size_t size, size_t alignment)
|
||||
{
|
||||
return NdbMem_Allocate(size);
|
||||
}
|
||||
|
||||
|
||||
void NdbMem_Free(void* ptr)
|
||||
{
|
||||
static SIGSELECT free_sig[] = {1,MMS_FREE_REGION_REPLY};
|
||||
union SIGNAL *sig;
|
||||
|
||||
/* Free a region in the callers domain. */
|
||||
sig = alloc(sizeof(struct MmsFreeRegionRequest),
|
||||
MMS_FREE_REGION_REQUEST);
|
||||
sig->mmsFreeRegionRequest.address = (U32)ptr;
|
||||
send(&sig, ose_mms_);
|
||||
sig = receive(free_sig);
|
||||
|
||||
if (sig->mmsFreeRegionReply.status != MMS_SUCCESS){
|
||||
ndbout_c("The MMS Region could not be deallocated.\r\n");
|
||||
error(sig->mmsFreeRegionReply.status);
|
||||
};
|
||||
free_buf(&sig);
|
||||
}
|
||||
|
||||
int NdbMem_MemLockAll(){
|
||||
return -1;
|
||||
}
|
||||
|
||||
int NdbMem_MemUnlockAll(){
|
||||
return -1;
|
||||
}
|
||||
|
||||
#else
|
||||
#include <stdlib.h>
|
||||
|
||||
|
||||
void NdbMem_Create()
|
||||
{
|
||||
/* Do nothing */
|
||||
return;
|
||||
}
|
||||
|
||||
void NdbMem_Destroy()
|
||||
{
|
||||
/* Do nothing */
|
||||
return;
|
||||
}
|
||||
|
||||
void* NdbMem_Allocate(size_t size)
|
||||
{
|
||||
assert(size > 0);
|
||||
return (void*)malloc(size);
|
||||
}
|
||||
|
||||
void* NdbMem_AllocateAlign(size_t size, size_t alignment)
|
||||
{
|
||||
/*
|
||||
return (void*)memalign(alignment, size);
|
||||
TEMP fix
|
||||
*/
|
||||
return (void*)malloc(size);
|
||||
}
|
||||
|
||||
|
||||
void NdbMem_Free(void* ptr)
|
||||
{
|
||||
free(ptr);
|
||||
}
|
||||
|
||||
|
||||
int NdbMem_MemLockAll(){
|
||||
return -1;
|
||||
}
|
||||
|
||||
int NdbMem_MemUnlockAll(){
|
||||
return -1;
|
||||
}
|
||||
|
||||
#endif
|
@@ -1,53 +0,0 @@
|
||||
/* Copyright (C) 2003 MySQL AB
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||
|
||||
#include "NdbMem.h"
|
||||
|
||||
extern "C"
|
||||
void NdbMem_Create()
|
||||
{
|
||||
}
|
||||
extern "C"
|
||||
void NdbMem_Destroy()
|
||||
{
|
||||
}
|
||||
|
||||
extern "C"
|
||||
void* NdbMem_Allocate(size_t size)
|
||||
{
|
||||
return new char[size];
|
||||
}
|
||||
|
||||
extern "C"
|
||||
void* NdbMem_AllocateAlign(size_t size, size_t alignment)
|
||||
{
|
||||
return NdbMem_Allocate(size);
|
||||
}
|
||||
|
||||
extern "C"
|
||||
void NdbMem_Free(void* ptr)
|
||||
{
|
||||
delete [] (char *)(ptr);
|
||||
}
|
||||
|
||||
int NdbMem_MemLockAll(){
|
||||
return -1;
|
||||
}
|
||||
|
||||
int NdbMem_MemUnlockAll(){
|
||||
return -1;
|
||||
}
|
||||
|
@@ -1,85 +0,0 @@
|
||||
/* Copyright (C) 2003 MySQL AB
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||
|
||||
|
||||
#include "NdbMutex.h"
|
||||
|
||||
#include <pthread.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
|
||||
NdbMutex* NdbMutex_Create(void)
|
||||
{
|
||||
NdbMutex* pNdbMutex;
|
||||
|
||||
pNdbMutex = create_sem(1);
|
||||
|
||||
return pNdbMutex;
|
||||
}
|
||||
|
||||
|
||||
int NdbMutex_Destroy(NdbMutex* p_mutex)
|
||||
{
|
||||
|
||||
if (p_mutex == NULL)
|
||||
return -1;
|
||||
|
||||
kill_sem(p_mutex);
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
|
||||
int NdbMutex_Lock(NdbMutex* p_mutex)
|
||||
{
|
||||
if (p_mutex == NULL)
|
||||
return -1;
|
||||
|
||||
wait_sem(p_mutex);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int NdbMutex_Unlock(NdbMutex* p_mutex)
|
||||
{
|
||||
|
||||
if (p_mutex == NULL)
|
||||
return -1;
|
||||
|
||||
signal_sem(p_mutex);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int NdbMutex_Trylock(NdbMutex* p_mutex)
|
||||
{
|
||||
int result = -1;
|
||||
|
||||
if (p_mutex != NULL) {
|
||||
OSSEMVAL semvalue = get_sem(p_mutex);
|
||||
if (semvalue > 0) {
|
||||
wait_sem(p_mutex);
|
||||
result = 0;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
|
||||
}
|
||||
|
@@ -1,96 +0,0 @@
|
||||
/* Copyright (C) 2003 MySQL AB
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||
|
||||
#include <ndb_global.h>
|
||||
|
||||
#include "NdbOut.hpp"
|
||||
|
||||
#if defined NDB_SOFTOSE
|
||||
#include <dbgprintf.h>
|
||||
#define printfunc dbgprintf
|
||||
#else
|
||||
#define printfunc printf
|
||||
#endif
|
||||
|
||||
static char const* const endlineString = "\r\n";
|
||||
|
||||
static int CtrlC = 0;
|
||||
NdbOut ndbout;
|
||||
|
||||
|
||||
NdbOut& NdbOut::operator<<(int aVal)
|
||||
{
|
||||
char* format;
|
||||
char HexFormat[] = "0x%08x";
|
||||
char DecFormat[] = "%d";
|
||||
if (isHexFormat == 1)
|
||||
format = HexFormat;
|
||||
else
|
||||
format = DecFormat;
|
||||
|
||||
printfunc(format, aVal);
|
||||
return *this;
|
||||
}
|
||||
|
||||
NdbOut& NdbOut::operator<<(char* pVal)
|
||||
{
|
||||
printfunc("%s", pVal);
|
||||
return *this;
|
||||
}
|
||||
|
||||
NdbOut& NdbOut::endline()
|
||||
{
|
||||
isHexFormat = 0; // Reset hex to normal, if user forgot this
|
||||
printfunc(endlineString);
|
||||
return *this;
|
||||
}
|
||||
|
||||
NdbOut& NdbOut::flushline()
|
||||
{
|
||||
isHexFormat = 0; // Reset hex to normal, if user forgot this
|
||||
return *this;
|
||||
}
|
||||
|
||||
NdbOut& NdbOut::setHexFormat(int _format)
|
||||
{
|
||||
isHexFormat = _format;
|
||||
return *this;
|
||||
}
|
||||
|
||||
NdbOut::NdbOut()
|
||||
{
|
||||
CtrlC = 0;
|
||||
isHexFormat = 0;
|
||||
}
|
||||
|
||||
NdbOut::~NdbOut()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
|
||||
extern "C"
|
||||
void
|
||||
ndbout_c(const char * fmt, ...){
|
||||
va_list ap;
|
||||
char buf[1000];
|
||||
|
||||
va_start(ap, fmt);
|
||||
if (fmt != 0)
|
||||
vsnprintf(buf, sizeof(buf)-1, fmt, ap);
|
||||
ndbout << buf << endl;
|
||||
va_end(ap);
|
||||
}
|
@@ -1,36 +0,0 @@
|
||||
/* Copyright (C) 2003 MySQL AB
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||
|
||||
|
||||
#include "NdbSleep.h"
|
||||
|
||||
#include <ose.h>
|
||||
|
||||
|
||||
int
|
||||
NdbSleep_MilliSleep(int milliseconds){
|
||||
const OSTIME millisecond_delay = milliseconds;
|
||||
delay(millisecond_delay);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
NdbSleep_SecSleep(int seconds){
|
||||
const OSTIME millisecond_delay = seconds*1000;
|
||||
delay(millisecond_delay);
|
||||
return 0;
|
||||
}
|
||||
|
@@ -1,38 +0,0 @@
|
||||
/* Copyright (C) 2003 MySQL AB
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||
|
||||
|
||||
#include "NdbTCP.h"
|
||||
|
||||
|
||||
int
|
||||
Ndb_getInAddr(struct in_addr * dst, const char *address) {
|
||||
struct hostent * host;
|
||||
host = gethostbyname_r(address);
|
||||
if(host != 0){
|
||||
dst->s_addr = ((struct in_addr *) *host->h_addr_list)->s_addr;
|
||||
free_buf((union SIGNAL **)&host);
|
||||
return 0;
|
||||
}
|
||||
/* Try it as aaa.bbb.ccc.ddd. */
|
||||
dst->s_addr = inet_addr(address);
|
||||
if (dst->s_addr != INADDR_NONE) {
|
||||
return 0;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@@ -1,183 +0,0 @@
|
||||
/* Copyright (C) 2003 MySQL AB
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||
|
||||
|
||||
#include "NdbThread.h"
|
||||
#include <pthread.h>
|
||||
#include <malloc.h>
|
||||
#include <string.h>
|
||||
#include <NdbOut.hpp>
|
||||
|
||||
#define MAX_THREAD_NAME 16
|
||||
|
||||
|
||||
struct NdbThread
|
||||
{
|
||||
PROCESS pid;
|
||||
char thread_name[MAX_THREAD_NAME];
|
||||
};
|
||||
|
||||
#define NDBTHREAD_SIGBASE 4010
|
||||
|
||||
#define NDBTHREAD_START (NDBTHREAD_SIGBASE + 1) /* !-SIGNO(struct NdbThreadStart)-! */
|
||||
|
||||
struct NdbThreadStart
|
||||
{
|
||||
SIGSELECT sigNo;
|
||||
NDB_THREAD_FUNC* func;
|
||||
NDB_THREAD_ARG arg;
|
||||
};
|
||||
|
||||
struct NdbThreadStopped
|
||||
{
|
||||
SIGSELECT sigNo;
|
||||
};
|
||||
|
||||
union SIGNAL
|
||||
{
|
||||
SIGSELECT sigNo;
|
||||
struct NdbThreadStart threadStart;
|
||||
struct NdbThreadStopped threadStopped;
|
||||
};
|
||||
|
||||
OS_PROCESS(thread_starter){
|
||||
static const SIGSELECT sel_start[] = {1, NDBTHREAD_START};
|
||||
struct NdbThreadStart* sigstart;
|
||||
union SIGNAL* sig;
|
||||
|
||||
/* Receive function adress and params */
|
||||
sig = receive((SIGSELECT*)sel_start);
|
||||
if (sig != NIL){
|
||||
if (sig->sigNo == NDBTHREAD_START){
|
||||
sigstart = ((struct NdbThreadStart*)sig);
|
||||
/* Execute function with arg */
|
||||
(*sigstart->func)(sigstart->arg);
|
||||
}else{
|
||||
assert(1==0);
|
||||
}
|
||||
free_buf(&sig);
|
||||
}
|
||||
}
|
||||
|
||||
struct NdbThread* NdbThread_Create(NDB_THREAD_FUNC* p_thread_func,
|
||||
NDB_THREAD_ARG *p_thread_arg,
|
||||
const NDB_THREAD_STACKSIZE thread_stack_size,
|
||||
const char* p_thread_name,
|
||||
NDB_THREAD_PRIO thread_prio)
|
||||
{
|
||||
struct NdbThread* tmpThread;
|
||||
union SIGNAL* sig;
|
||||
int ose_prio;
|
||||
|
||||
if (p_thread_func == NULL)
|
||||
return 0;
|
||||
|
||||
tmpThread = (struct NdbThread*)malloc(sizeof(struct NdbThread));
|
||||
if (tmpThread == NULL)
|
||||
return NULL;
|
||||
|
||||
strncpy((char*)&tmpThread->thread_name, p_thread_name, MAX_THREAD_NAME);
|
||||
|
||||
switch(thread_prio){
|
||||
case NDB_THREAD_PRIO_HIGHEST:
|
||||
ose_prio = 1;
|
||||
break;
|
||||
case NDB_THREAD_PRIO_HIGH:
|
||||
ose_prio = 10;
|
||||
break;
|
||||
case NDB_THREAD_PRIO_MEAN:
|
||||
ose_prio = 16;
|
||||
break;
|
||||
case NDB_THREAD_PRIO_LOW:
|
||||
ose_prio = 23;
|
||||
break;
|
||||
case NDB_THREAD_PRIO_LOWEST:
|
||||
ose_prio = 31;
|
||||
break;
|
||||
default:
|
||||
return NULL;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Create process */
|
||||
tmpThread->pid = create_process(OS_PRI_PROC, /* Process type */
|
||||
(char*)p_thread_name, /* Name */
|
||||
thread_starter, /* Entry point */
|
||||
thread_stack_size, /* Stack size */
|
||||
ose_prio, /* Priority */
|
||||
0, /* Time slice */
|
||||
get_bid(current_process()), /* Block */
|
||||
NULL, /* Redir table */
|
||||
0,
|
||||
0);
|
||||
|
||||
/* Send params to process */
|
||||
sig = alloc(sizeof(struct NdbThreadStart), NDBTHREAD_START);
|
||||
((struct NdbThreadStart*)sig)->func = p_thread_func;
|
||||
((struct NdbThreadStart*)sig)->arg = p_thread_arg;
|
||||
send(&sig, tmpThread->pid);
|
||||
|
||||
/* Enable NDB_HOME environment variable for the thread */
|
||||
{
|
||||
/* Hardcoded NDB_HOME...*/
|
||||
char* ndb_home_env = get_env(current_process(), "NDB_HOME");
|
||||
if (ndb_home_env != NULL)
|
||||
{
|
||||
/* Set NDB_HOME */
|
||||
int rc = set_env(tmpThread->pid, "NDB_HOME", ndb_home_env);
|
||||
if (rc != 0)
|
||||
{
|
||||
/* Not really a problem */
|
||||
}
|
||||
} /* Enable NDB_HOME */
|
||||
}
|
||||
|
||||
/* Start process */
|
||||
start(tmpThread->pid);
|
||||
|
||||
return tmpThread;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void NdbThread_Destroy(struct NdbThread** p_thread)
|
||||
{
|
||||
free(* p_thread); * p_thread = 0;
|
||||
}
|
||||
|
||||
|
||||
int NdbThread_WaitFor(struct NdbThread* p_wait_thread, void** status)
|
||||
{
|
||||
while(hunt(p_wait_thread->thread_name, 0, NULL, NULL) != 0)
|
||||
delay(1000);
|
||||
|
||||
* status = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void NdbThread_Exit(int a)
|
||||
{
|
||||
kill_proc(current_process());
|
||||
}
|
||||
|
||||
|
||||
int NdbThread_SetConcurrencyLevel(int level)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
@@ -1,64 +0,0 @@
|
||||
/* Copyright (C) 2003 MySQL AB
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||
|
||||
|
||||
#include "NdbTick.h"
|
||||
#include <time.h>
|
||||
|
||||
#define NANOSEC_PER_SEC 1000000000
|
||||
#define MICROSEC_PER_SEC 1000000
|
||||
#define MILLISEC_PER_SEC 1000
|
||||
#define MICROSEC_PER_MILLISEC 1000
|
||||
#define MILLISEC_PER_NANOSEC 1000000
|
||||
|
||||
#ifdef NDB_OSE
|
||||
NDB_TICKS NdbTick_CurrentMillisecond(void)
|
||||
{
|
||||
return get_ticks()*4;
|
||||
}
|
||||
#include <rtc.h>
|
||||
int
|
||||
NdbTick_CurrentMicrosecond(NDB_TICKS * secs, Uint32 * micros){
|
||||
struct TimePair tvp;
|
||||
rtc_get_time(&tvp);
|
||||
* secs = tvp.seconds;
|
||||
* micros = tvp.micros;
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#if defined NDB_SOFTOSE
|
||||
NDB_TICKS NdbTick_CurrentMillisecond(void)
|
||||
{
|
||||
/**
|
||||
* Depends on the interval counter in solaris
|
||||
* that means each "tick" in OSE is really 10 milliseconds
|
||||
*/
|
||||
return get_ticks()*10;
|
||||
}
|
||||
|
||||
#include <rtc.h>
|
||||
int
|
||||
NdbTick_CurrentMicrosecond(NDB_TICKS * secs, Uint32 * micros){
|
||||
struct TimePair tvp;
|
||||
rtc_get_time(&tvp);
|
||||
* secs = tvp.seconds;
|
||||
* micros = tvp.micros;
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
@@ -1,15 +0,0 @@
|
||||
include .defs.mk
|
||||
|
||||
TYPE := kernel
|
||||
|
||||
BIN_TARGET := PortLibTest
|
||||
BIN_TARGET_ARCHIVES := portlib general
|
||||
|
||||
SOURCES = NdbPortLibTest.cpp
|
||||
|
||||
include $(NDB_TOP)/Epilogue.mk
|
||||
|
||||
|
||||
|
||||
|
||||
|
@@ -1,30 +0,0 @@
|
||||
include .defs.mk
|
||||
|
||||
TYPE := util
|
||||
|
||||
PIC_ARCHIVE := Y
|
||||
ARCHIVE_TARGET := portlib
|
||||
|
||||
SOURCES.c = NdbCondition.c \
|
||||
NdbMutex.c \
|
||||
NdbSleep.c \
|
||||
NdbTick.c \
|
||||
NdbEnv.c \
|
||||
NdbThread.c \
|
||||
NdbHost.c \
|
||||
NdbTCP.c \
|
||||
NdbDaemon.c
|
||||
|
||||
ifeq ($(NDB_OS), SOFTOSE)
|
||||
SOURCES += NdbMem_SoftOse.cpp
|
||||
else
|
||||
SOURCES.c += NdbMem.c
|
||||
endif
|
||||
|
||||
include $(NDB_TOP)/Epilogue.mk
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
@@ -1,183 +0,0 @@
|
||||
/* Copyright (C) 2003 MySQL AB
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||
|
||||
|
||||
#include <winsock2.h>
|
||||
#include <ws2tcpip.h>
|
||||
#include <windows.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#include "NdbCondition.h"
|
||||
#include <NdbMutex.h>
|
||||
|
||||
|
||||
struct NdbCondition
|
||||
{
|
||||
long nWaiters;
|
||||
NdbMutex* pNdbMutexWaitersLock;
|
||||
HANDLE hSemaphore;
|
||||
HANDLE hEventWaitersDone;
|
||||
int bWasBroadcast;
|
||||
};
|
||||
|
||||
|
||||
struct NdbCondition*
|
||||
NdbCondition_Create(void)
|
||||
{
|
||||
int result = 0;
|
||||
struct NdbCondition* pNdbCondition = (struct NdbCondition*)malloc(sizeof(struct NdbCondition));
|
||||
if(!pNdbCondition)
|
||||
return 0;
|
||||
|
||||
pNdbCondition->nWaiters = 0;
|
||||
pNdbCondition->bWasBroadcast = 0;
|
||||
if(!(pNdbCondition->hSemaphore = CreateSemaphore(0, 0, MAXLONG, 0)))
|
||||
result = -1;
|
||||
else if(!(pNdbCondition->pNdbMutexWaitersLock = NdbMutex_Create()))
|
||||
result = -1;
|
||||
else if(!(pNdbCondition->hEventWaitersDone = CreateEvent(0, 0, 0, 0)))
|
||||
result = -1;
|
||||
|
||||
assert(!result);
|
||||
return pNdbCondition;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
NdbCondition_Wait(struct NdbCondition* p_cond,
|
||||
NdbMutex* p_mutex)
|
||||
{
|
||||
int result;
|
||||
int bLastWaiter;
|
||||
if(!p_cond || !p_mutex)
|
||||
return 1;
|
||||
|
||||
NdbMutex_Lock(p_cond->pNdbMutexWaitersLock);
|
||||
p_cond->nWaiters++;
|
||||
NdbMutex_Unlock(p_cond->pNdbMutexWaitersLock);
|
||||
|
||||
if(NdbMutex_Unlock(p_mutex))
|
||||
return -1;
|
||||
result = WaitForSingleObject (p_cond->hSemaphore, INFINITE);
|
||||
|
||||
NdbMutex_Lock(p_cond->pNdbMutexWaitersLock);
|
||||
p_cond->nWaiters--;
|
||||
bLastWaiter = (p_cond->bWasBroadcast && p_cond->nWaiters==0);
|
||||
NdbMutex_Unlock(p_cond->pNdbMutexWaitersLock);
|
||||
|
||||
if(result==WAIT_OBJECT_0 && bLastWaiter)
|
||||
SetEvent(p_cond->hEventWaitersDone);
|
||||
|
||||
NdbMutex_Lock(p_mutex);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
NdbCondition_WaitTimeout(struct NdbCondition* p_cond,
|
||||
NdbMutex* p_mutex,
|
||||
int msecs)
|
||||
{
|
||||
int result;
|
||||
int bLastWaiter;
|
||||
if (!p_cond || !p_mutex)
|
||||
return 1;
|
||||
|
||||
NdbMutex_Lock(p_cond->pNdbMutexWaitersLock);
|
||||
p_cond->nWaiters++;
|
||||
NdbMutex_Unlock(p_cond->pNdbMutexWaitersLock);
|
||||
if(msecs<0)
|
||||
msecs = 0;
|
||||
|
||||
if(NdbMutex_Unlock(p_mutex))
|
||||
return -1;
|
||||
result = WaitForSingleObject(p_cond->hSemaphore, msecs);
|
||||
|
||||
NdbMutex_Lock(p_cond->pNdbMutexWaitersLock);
|
||||
p_cond->nWaiters--;
|
||||
bLastWaiter = (p_cond->bWasBroadcast && p_cond->nWaiters==0);
|
||||
NdbMutex_Unlock(p_cond->pNdbMutexWaitersLock);
|
||||
|
||||
if(result!=WAIT_OBJECT_0)
|
||||
result = -1;
|
||||
|
||||
if(bLastWaiter)
|
||||
SetEvent(p_cond->hEventWaitersDone);
|
||||
|
||||
NdbMutex_Lock(p_mutex);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
NdbCondition_Signal(struct NdbCondition* p_cond)
|
||||
{
|
||||
int bHaveWaiters;
|
||||
if(!p_cond)
|
||||
return 1;
|
||||
|
||||
NdbMutex_Lock(p_cond->pNdbMutexWaitersLock);
|
||||
bHaveWaiters = (p_cond->nWaiters > 0);
|
||||
NdbMutex_Unlock(p_cond->pNdbMutexWaitersLock);
|
||||
|
||||
if(bHaveWaiters)
|
||||
return (ReleaseSemaphore(p_cond->hSemaphore, 1, 0) ? 0 : -1);
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int NdbCondition_Broadcast(struct NdbCondition* p_cond)
|
||||
{
|
||||
int bHaveWaiters;
|
||||
int result = 0;
|
||||
if(!p_cond)
|
||||
return 1;
|
||||
|
||||
NdbMutex_Lock(p_cond->pNdbMutexWaitersLock);
|
||||
bHaveWaiters = 0;
|
||||
if(p_cond->nWaiters > 0)
|
||||
{
|
||||
p_cond->bWasBroadcast = !0;
|
||||
bHaveWaiters = 1;
|
||||
}
|
||||
NdbMutex_Unlock(p_cond->pNdbMutexWaitersLock);
|
||||
if(bHaveWaiters)
|
||||
{
|
||||
if(!ReleaseSemaphore(p_cond->hSemaphore, p_cond->nWaiters, 0))
|
||||
result = -1;
|
||||
else if(WaitForSingleObject (p_cond->hEventWaitersDone, INFINITE) != WAIT_OBJECT_0)
|
||||
result = -1;
|
||||
p_cond->bWasBroadcast = 0;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
int NdbCondition_Destroy(struct NdbCondition* p_cond)
|
||||
{
|
||||
int result;
|
||||
if(!p_cond)
|
||||
return 1;
|
||||
|
||||
CloseHandle(p_cond->hEventWaitersDone);
|
||||
NdbMutex_Destroy(p_cond->pNdbMutexWaitersLock);
|
||||
result = (CloseHandle(p_cond->hSemaphore) ? 0 : -1);
|
||||
|
||||
free(p_cond);
|
||||
return 0;
|
||||
}
|
||||
|
@@ -1,47 +0,0 @@
|
||||
/* Copyright (C) 2003 MySQL AB
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||
|
||||
#include <ndb_global.h>
|
||||
#include "NdbDaemon.h"
|
||||
|
||||
#define NdbDaemon_ErrorSize 500
|
||||
long NdbDaemon_DaemonPid;
|
||||
int NdbDaemon_ErrorCode;
|
||||
char NdbDaemon_ErrorText[NdbDaemon_ErrorSize];
|
||||
|
||||
int
|
||||
NdbDaemon_Make(const char* lockfile, const char* logfile, unsigned flags)
|
||||
{
|
||||
/* Fail */
|
||||
snprintf(NdbDaemon_ErrorText, NdbDaemon_ErrorSize,
|
||||
"Daemon mode not implemented");
|
||||
return -1;
|
||||
}
|
||||
|
||||
#ifdef NDB_DAEMON_TEST
|
||||
|
||||
int
|
||||
main()
|
||||
{
|
||||
if (NdbDaemon_Make("test.pid", "test.log", 0) == -1) {
|
||||
fprintf(stderr, "NdbDaemon_Make: %s\n", NdbDaemon_ErrorText);
|
||||
return 1;
|
||||
}
|
||||
sleep(10);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
@@ -1,33 +0,0 @@
|
||||
/* Copyright (C) 2003 MySQL AB
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||
|
||||
|
||||
#include "NdbEnv.h"
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
const char* NdbEnv_GetEnv(const char* name, char * buf, int buflen)
|
||||
{
|
||||
char* p = NULL;
|
||||
p = getenv(name);
|
||||
|
||||
if (p != NULL && buf != NULL){
|
||||
strncpy(buf, p, buflen);
|
||||
buf[buflen-1] = 0;
|
||||
}
|
||||
return p;
|
||||
}
|
||||
|
@@ -1,53 +0,0 @@
|
||||
/* Copyright (C) 2003 MySQL AB
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||
|
||||
|
||||
#include "NdbHost.h"
|
||||
#include <windows.h>
|
||||
#include <process.h>
|
||||
|
||||
|
||||
int NdbHost_GetHostName(char* buf)
|
||||
{
|
||||
/* We must initialize TCP/IP if we want to call gethostname */
|
||||
WORD wVersionRequested;
|
||||
WSADATA wsaData;
|
||||
int err;
|
||||
|
||||
wVersionRequested = MAKEWORD( 2, 0 );
|
||||
err = WSAStartup( wVersionRequested, &wsaData );
|
||||
if ( err != 0 ) {
|
||||
/**
|
||||
* Tell the user that we couldn't find a usable
|
||||
* WinSock DLL.
|
||||
*/
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Get host name */
|
||||
if(gethostname(buf, MAXHOSTNAMELEN))
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int NdbHost_GetProcessId(void)
|
||||
{
|
||||
return _getpid();
|
||||
}
|
||||
|
@@ -1,235 +0,0 @@
|
||||
/* Copyright (C) 2003 MySQL AB
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
#include "NdbMem.h"
|
||||
|
||||
|
||||
struct AWEINFO
|
||||
{
|
||||
SIZE_T dwSizeInBytesRequested;
|
||||
ULONG_PTR nNumberOfPagesRequested;
|
||||
ULONG_PTR nNumberOfPagesActual;
|
||||
ULONG_PTR nNumberOfPagesFreed;
|
||||
ULONG_PTR* pnPhysicalMemoryPageArray;
|
||||
void* pRegionReserved;
|
||||
};
|
||||
|
||||
const size_t cNdbMem_nMaxAWEinfo = 256;
|
||||
size_t gNdbMem_nAWEinfo = 0;
|
||||
|
||||
struct AWEINFO* gNdbMem_pAWEinfo = 0;
|
||||
|
||||
|
||||
void ShowLastError(const char* szContext, const char* szFunction)
|
||||
{
|
||||
DWORD dwError = GetLastError();
|
||||
LPVOID lpMsgBuf;
|
||||
FormatMessage(
|
||||
FORMAT_MESSAGE_ALLOCATE_BUFFER |
|
||||
FORMAT_MESSAGE_FROM_SYSTEM |
|
||||
FORMAT_MESSAGE_IGNORE_INSERTS,
|
||||
NULL,
|
||||
dwError,
|
||||
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
|
||||
(LPTSTR)&lpMsgBuf,
|
||||
0,
|
||||
NULL
|
||||
);
|
||||
printf("%s : %s failed : %lu : %s\n", szContext, szFunction, dwError, (char*)lpMsgBuf);
|
||||
LocalFree(lpMsgBuf);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void NdbMem_Create()
|
||||
{
|
||||
// Address Windowing Extensions
|
||||
struct PRIVINFO
|
||||
{
|
||||
DWORD Count;
|
||||
LUID_AND_ATTRIBUTES Privilege[1];
|
||||
} Info;
|
||||
|
||||
HANDLE hProcess = GetCurrentProcess();
|
||||
HANDLE hToken;
|
||||
if(!OpenProcessToken(hProcess, TOKEN_ADJUST_PRIVILEGES, &hToken))
|
||||
{
|
||||
ShowLastError("NdbMem_Create", "OpenProcessToken");
|
||||
}
|
||||
|
||||
Info.Count = 1;
|
||||
Info.Privilege[0].Attributes = SE_PRIVILEGE_ENABLED;
|
||||
if(!LookupPrivilegeValue(0, SE_LOCK_MEMORY_NAME, &(Info.Privilege[0].Luid)))
|
||||
{
|
||||
ShowLastError("NdbMem_Create", "LookupPrivilegeValue");
|
||||
}
|
||||
|
||||
if(!AdjustTokenPrivileges(hToken, FALSE, (PTOKEN_PRIVILEGES)&Info, 0, 0, 0))
|
||||
{
|
||||
ShowLastError("NdbMem_Create", "AdjustTokenPrivileges");
|
||||
}
|
||||
|
||||
if(!CloseHandle(hToken))
|
||||
{
|
||||
ShowLastError("NdbMem_Create", "CloseHandle");
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void NdbMem_Destroy()
|
||||
{
|
||||
/* Do nothing */
|
||||
return;
|
||||
}
|
||||
|
||||
void* NdbMem_Allocate(size_t size)
|
||||
{
|
||||
// Address Windowing Extensions
|
||||
struct AWEINFO* pAWEinfo;
|
||||
HANDLE hProcess;
|
||||
SYSTEM_INFO sysinfo;
|
||||
|
||||
if(!gNdbMem_pAWEinfo)
|
||||
{
|
||||
gNdbMem_pAWEinfo = VirtualAlloc(0,
|
||||
sizeof(struct AWEINFO)*cNdbMem_nMaxAWEinfo,
|
||||
MEM_COMMIT|MEM_RESERVE, PAGE_READWRITE);
|
||||
}
|
||||
|
||||
assert(gNdbMem_nAWEinfo < cNdbMem_nMaxAWEinfo);
|
||||
pAWEinfo = gNdbMem_pAWEinfo+gNdbMem_nAWEinfo++;
|
||||
|
||||
hProcess = GetCurrentProcess();
|
||||
GetSystemInfo(&sysinfo);
|
||||
pAWEinfo->nNumberOfPagesRequested = (size+sysinfo.dwPageSize-1)/sysinfo.dwPageSize;
|
||||
pAWEinfo->pnPhysicalMemoryPageArray = VirtualAlloc(0,
|
||||
sizeof(ULONG_PTR)*pAWEinfo->nNumberOfPagesRequested,
|
||||
MEM_COMMIT|MEM_RESERVE, PAGE_READWRITE);
|
||||
pAWEinfo->nNumberOfPagesActual = pAWEinfo->nNumberOfPagesRequested;
|
||||
if(!AllocateUserPhysicalPages(hProcess, &(pAWEinfo->nNumberOfPagesActual), pAWEinfo->pnPhysicalMemoryPageArray))
|
||||
{
|
||||
ShowLastError("NdbMem_Allocate", "AllocateUserPhysicalPages");
|
||||
return 0;
|
||||
}
|
||||
if(pAWEinfo->nNumberOfPagesRequested != pAWEinfo->nNumberOfPagesActual)
|
||||
{
|
||||
ShowLastError("NdbMem_Allocate", "nNumberOfPagesRequested != nNumberOfPagesActual");
|
||||
return 0;
|
||||
}
|
||||
|
||||
pAWEinfo->dwSizeInBytesRequested = size;
|
||||
pAWEinfo->pRegionReserved = VirtualAlloc(0, pAWEinfo->dwSizeInBytesRequested, MEM_RESERVE | MEM_PHYSICAL, PAGE_READWRITE);
|
||||
if(!pAWEinfo->pRegionReserved)
|
||||
{
|
||||
ShowLastError("NdbMem_Allocate", "VirtualAlloc");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if(!MapUserPhysicalPages(pAWEinfo->pRegionReserved, pAWEinfo->nNumberOfPagesActual, pAWEinfo->pnPhysicalMemoryPageArray))
|
||||
{
|
||||
ShowLastError("NdbMem_Allocate", "MapUserPhysicalPages");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
printf("allocate AWE memory: %lu bytes, %lu pages, address %lx\n",
|
||||
pAWEinfo->dwSizeInBytesRequested,
|
||||
pAWEinfo->nNumberOfPagesActual,
|
||||
pAWEinfo->pRegionReserved);
|
||||
*/
|
||||
return pAWEinfo->pRegionReserved;
|
||||
}
|
||||
|
||||
|
||||
void* NdbMem_AllocateAlign(size_t size, size_t alignment)
|
||||
{
|
||||
/*
|
||||
return (void*)memalign(alignment, size);
|
||||
TEMP fix
|
||||
*/
|
||||
return NdbMem_Allocate(size);
|
||||
}
|
||||
|
||||
|
||||
void NdbMem_Free(void* ptr)
|
||||
{
|
||||
// VirtualFree(ptr, 0, MEM_DECOMMIT|MEM_RELEASE);
|
||||
|
||||
// Address Windowing Extensions
|
||||
struct AWEINFO* pAWEinfo = 0;
|
||||
size_t i;
|
||||
HANDLE hProcess;
|
||||
|
||||
for(i=0; i<gNdbMem_nAWEinfo; ++i)
|
||||
{
|
||||
if(ptr==gNdbMem_pAWEinfo[i].pRegionReserved)
|
||||
{
|
||||
pAWEinfo = gNdbMem_pAWEinfo+i;
|
||||
}
|
||||
}
|
||||
if(!pAWEinfo)
|
||||
{
|
||||
ShowLastError("NdbMem_Free", "ptr is not AWE memory");
|
||||
}
|
||||
|
||||
hProcess = GetCurrentProcess();
|
||||
if(!MapUserPhysicalPages(ptr, pAWEinfo->nNumberOfPagesActual, 0))
|
||||
{
|
||||
ShowLastError("NdbMem_Free", "MapUserPhysicalPages");
|
||||
}
|
||||
|
||||
if(!VirtualFree(ptr, 0, MEM_RELEASE))
|
||||
{
|
||||
ShowLastError("NdbMem_Free", "VirtualFree");
|
||||
}
|
||||
|
||||
pAWEinfo->nNumberOfPagesFreed = pAWEinfo->nNumberOfPagesActual;
|
||||
if(!FreeUserPhysicalPages(hProcess, &(pAWEinfo->nNumberOfPagesFreed), pAWEinfo->pnPhysicalMemoryPageArray))
|
||||
{
|
||||
ShowLastError("NdbMem_Free", "FreeUserPhysicalPages");
|
||||
}
|
||||
|
||||
VirtualFree(pAWEinfo->pnPhysicalMemoryPageArray, 0, MEM_DECOMMIT|MEM_RELEASE);
|
||||
}
|
||||
|
||||
|
||||
int NdbMem_MemLockAll()
|
||||
{
|
||||
/*
|
||||
HANDLE hProcess = GetCurrentProcess();
|
||||
SIZE_T nMinimumWorkingSetSize;
|
||||
SIZE_T nMaximumWorkingSetSize;
|
||||
GetProcessWorkingSetSize(hProcess, &nMinimumWorkingSetSize, &nMaximumWorkingSetSize);
|
||||
ndbout << "nMinimumWorkingSetSize=" << nMinimumWorkingSetSize << ", nMaximumWorkingSetSize=" << nMaximumWorkingSetSize << endl;
|
||||
|
||||
SetProcessWorkingSetSize(hProcess, 50000000, 100000000);
|
||||
|
||||
GetProcessWorkingSetSize(hProcess, &nMinimumWorkingSetSize, &nMaximumWorkingSetSize);
|
||||
ndbout << "nMinimumWorkingSetSize=" << nMinimumWorkingSetSize << ", nMaximumWorkingSetSize=" << nMaximumWorkingSetSize << endl;
|
||||
*/
|
||||
return -1;
|
||||
}
|
||||
|
||||
int NdbMem_MemUnlockAll()
|
||||
{
|
||||
//VirtualUnlock();
|
||||
return -1;
|
||||
}
|
||||
|
@@ -1,77 +0,0 @@
|
||||
/* Copyright (C) 2003 MySQL AB
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||
|
||||
|
||||
#include <winsock2.h>
|
||||
#include <ws2tcpip.h>
|
||||
#include <windows.h>
|
||||
#include <time.h>
|
||||
|
||||
#include "NdbMutex.h"
|
||||
|
||||
|
||||
NdbMutex* NdbMutex_Create(void)
|
||||
{
|
||||
NdbMutex* pNdbMutex = (NdbMutex*)malloc(sizeof(NdbMutex));
|
||||
if(!pNdbMutex)
|
||||
return 0;
|
||||
|
||||
InitializeCriticalSection(pNdbMutex);
|
||||
return pNdbMutex;
|
||||
}
|
||||
|
||||
|
||||
int NdbMutex_Destroy(NdbMutex* p_mutex)
|
||||
{
|
||||
if(!p_mutex)
|
||||
return -1;
|
||||
|
||||
DeleteCriticalSection(p_mutex);
|
||||
free(p_mutex);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int NdbMutex_Lock(NdbMutex* p_mutex)
|
||||
{
|
||||
if(!p_mutex)
|
||||
return -1;
|
||||
|
||||
EnterCriticalSection (p_mutex);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int NdbMutex_Unlock(NdbMutex* p_mutex)
|
||||
{
|
||||
if(!p_mutex)
|
||||
return -1;
|
||||
|
||||
LeaveCriticalSection(p_mutex);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int NdbMutex_Trylock(NdbMutex* p_mutex)
|
||||
{
|
||||
int result = -1;
|
||||
if(p_mutex)
|
||||
{
|
||||
result = (TryEnterCriticalSection(p_mutex) ? 0 : -1);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
@@ -1,35 +0,0 @@
|
||||
/* Copyright (C) 2003 MySQL AB
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||
|
||||
|
||||
#include "NdbSleep.h"
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
|
||||
int
|
||||
NdbSleep_MilliSleep(int milliseconds)
|
||||
{
|
||||
Sleep(milliseconds);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
NdbSleep_SecSleep(int seconds)
|
||||
{
|
||||
return NdbSleep_MilliSleep(seconds*1000);
|
||||
}
|
||||
|
@@ -1,39 +0,0 @@
|
||||
/* Copyright (C) 2003 MySQL AB
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||
|
||||
|
||||
#include "NdbTCP.h"
|
||||
|
||||
int
|
||||
Ndb_getInAddr(struct in_addr * dst, const char *address)
|
||||
{
|
||||
struct hostent * hostPtr;
|
||||
|
||||
/* Try it as aaa.bbb.ccc.ddd. */
|
||||
dst->s_addr = inet_addr(address);
|
||||
if (dst->s_addr != -1) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
hostPtr = gethostbyname(address);
|
||||
if (hostPtr != NULL) {
|
||||
dst->s_addr = ((struct in_addr *) *hostPtr->h_addr_list)->s_addr;
|
||||
return 0;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
@@ -1,117 +0,0 @@
|
||||
/* Copyright (C) 2003 MySQL AB
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||
|
||||
|
||||
#include <windows.h>
|
||||
#include <process.h>
|
||||
|
||||
#include "NdbThread.h"
|
||||
|
||||
|
||||
#define MAX_THREAD_NAME 16
|
||||
|
||||
typedef unsigned (WINAPI* NDB_WIN32_THREAD_FUNC)(void*);
|
||||
|
||||
|
||||
struct NdbThread
|
||||
{
|
||||
HANDLE hThread;
|
||||
unsigned nThreadId;
|
||||
char thread_name[MAX_THREAD_NAME];
|
||||
};
|
||||
|
||||
|
||||
struct NdbThread* NdbThread_Create(NDB_THREAD_FUNC *p_thread_func,
|
||||
NDB_THREAD_ARG *p_thread_arg,
|
||||
const NDB_THREAD_STACKSIZE thread_stack_size,
|
||||
const char* p_thread_name,
|
||||
NDB_THREAD_PRIO thread_prio)
|
||||
{
|
||||
struct NdbThread* tmpThread;
|
||||
unsigned initflag;
|
||||
int nPriority = 0;
|
||||
|
||||
if(!p_thread_func)
|
||||
return 0;
|
||||
|
||||
tmpThread = (struct NdbThread*)malloc(sizeof(struct NdbThread));
|
||||
if(!tmpThread)
|
||||
return 0;
|
||||
|
||||
strncpy((char*)&tmpThread->thread_name, p_thread_name, MAX_THREAD_NAME);
|
||||
|
||||
switch(thread_prio)
|
||||
{
|
||||
case NDB_THREAD_PRIO_HIGHEST: nPriority=THREAD_PRIORITY_HIGHEST; break;
|
||||
case NDB_THREAD_PRIO_HIGH: nPriority=THREAD_PRIORITY_ABOVE_NORMAL; break;
|
||||
case NDB_THREAD_PRIO_MEAN: nPriority=THREAD_PRIORITY_NORMAL; break;
|
||||
case NDB_THREAD_PRIO_LOW: nPriority=THREAD_PRIORITY_BELOW_NORMAL; break;
|
||||
case NDB_THREAD_PRIO_LOWEST: nPriority=THREAD_PRIORITY_LOWEST; break;
|
||||
}
|
||||
initflag = (nPriority ? CREATE_SUSPENDED : 0);
|
||||
|
||||
tmpThread->hThread = (HANDLE)_beginthreadex(0, thread_stack_size,
|
||||
(NDB_WIN32_THREAD_FUNC)p_thread_func, p_thread_arg,
|
||||
initflag, &tmpThread->nThreadId);
|
||||
|
||||
if(nPriority && tmpThread->hThread)
|
||||
{
|
||||
SetThreadPriority(tmpThread->hThread, nPriority);
|
||||
ResumeThread (tmpThread->hThread);
|
||||
}
|
||||
|
||||
assert(tmpThread->hThread);
|
||||
return tmpThread;
|
||||
}
|
||||
|
||||
|
||||
void NdbThread_Destroy(struct NdbThread** p_thread)
|
||||
{
|
||||
CloseHandle((*p_thread)->hThread);
|
||||
(*p_thread)->hThread = 0;
|
||||
free(*p_thread);
|
||||
*p_thread = 0;
|
||||
}
|
||||
|
||||
|
||||
int NdbThread_WaitFor(struct NdbThread* p_wait_thread, void** status)
|
||||
{
|
||||
void *local_status = 0;
|
||||
if (status == 0)
|
||||
status = &local_status;
|
||||
|
||||
if(WaitForSingleObject(p_wait_thread->hThread, INFINITE) == WAIT_OBJECT_0
|
||||
&& GetExitCodeThread(p_wait_thread->hThread, (LPDWORD)status))
|
||||
{
|
||||
CloseHandle(p_wait_thread->hThread);
|
||||
p_wait_thread->hThread = 0;
|
||||
return 0;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
void NdbThread_Exit(int status)
|
||||
{
|
||||
_endthreadex((DWORD) status);
|
||||
}
|
||||
|
||||
|
||||
int NdbThread_SetConcurrencyLevel(int level)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
@@ -1,64 +0,0 @@
|
||||
/* Copyright (C) 2003 MySQL AB
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||
|
||||
|
||||
#include <windows.h>
|
||||
#include "NdbTick.h"
|
||||
|
||||
/*
|
||||
#define FILETIME_PER_MICROSEC 10
|
||||
#define FILETIME_PER_MILLISEC 10000
|
||||
#define FILETIME_PER_SEC 10000000
|
||||
|
||||
|
||||
NDB_TICKS NdbTick_CurrentMillisecond(void)
|
||||
{
|
||||
ULONGLONG ullTime;
|
||||
GetSystemTimeAsFileTime((LPFILETIME)&ullTime);
|
||||
return (ullTime / FILETIME_PER_MILLISEC);
|
||||
}
|
||||
|
||||
int
|
||||
NdbTick_CurrentMicrosecond(NDB_TICKS * secs, Uint32 * micros)
|
||||
{
|
||||
ULONGLONG ullTime;
|
||||
GetSystemTimeAsFileTime((LPFILETIME)&ullTime);
|
||||
*secs = (ullTime / FILETIME_PER_SEC);
|
||||
*micros = (Uint32)((ullTime % FILETIME_PER_SEC) / FILETIME_PER_MICROSEC);
|
||||
return 0;
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
NDB_TICKS NdbTick_CurrentMillisecond(void)
|
||||
{
|
||||
LARGE_INTEGER liCount, liFreq;
|
||||
QueryPerformanceCounter(&liCount);
|
||||
QueryPerformanceFrequency(&liFreq);
|
||||
return (liCount.QuadPart*1000) / liFreq.QuadPart;
|
||||
}
|
||||
|
||||
int
|
||||
NdbTick_CurrentMicrosecond(NDB_TICKS * secs, Uint32 * micros)
|
||||
{
|
||||
LARGE_INTEGER liCount, liFreq;
|
||||
QueryPerformanceCounter(&liCount);
|
||||
QueryPerformanceFrequency(&liFreq);
|
||||
*secs = liCount.QuadPart / liFreq.QuadPart;
|
||||
liCount.QuadPart -= *secs * liFreq.QuadPart;
|
||||
*micros = (liCount.QuadPart*1000000) / liFreq.QuadPart;
|
||||
return 0;
|
||||
}
|
@@ -1,9 +0,0 @@
|
||||
include .defs.mk
|
||||
|
||||
DIRS =
|
||||
|
||||
ifneq ($(NDB_ODBC),N)
|
||||
DIRS += odbc
|
||||
endif
|
||||
|
||||
include $(NDB_TOP)/Epilogue.mk
|
@@ -1,59 +0,0 @@
|
||||
# before Epilogue.mk
|
||||
|
||||
CCFLAGS_LOC += -I..
|
||||
|
||||
CCFLAGS_LOC += \
|
||||
-I$(call fixpath,$(NDB_TOP)/include/ndbapi) \
|
||||
-I$(call fixpath,$(NDB_TOP)/include/util) \
|
||||
-I$(call fixpath,$(NDB_TOP)/include/portlib)
|
||||
|
||||
ifeq ($(NDB_OS),SOLARIS)
|
||||
|
||||
CCFLAGS_LOC += -I/usr/local/include
|
||||
|
||||
ifeq ($(NDB_COMPILER),GCC)
|
||||
LIBS_LOC += -Wl,-z,text
|
||||
CCFLAGS_WARNINGS += -Wno-unused -Wformat
|
||||
CCFLAGS_TOP += -D__STL_PTHREADS
|
||||
endif
|
||||
|
||||
ifeq ($(NDB_COMPILER),FORTE6)
|
||||
LIBS_LOC += -z text
|
||||
LIBS_SPEC += /usr/lib/libCrun.so.1
|
||||
endif
|
||||
|
||||
LIB_TARGET_LIBS += -lthread -lrt
|
||||
|
||||
endif
|
||||
ifneq ($(filter $(NDB_OS), LINUX MACOSX IBMAIX TRU64X),)
|
||||
|
||||
LIBS_LOC += -Wl,-z,text
|
||||
CCFLAGS_WARNINGS += -Wno-unused -Wformat
|
||||
GCC_VER := $(shell $(CC) --version)
|
||||
|
||||
ifeq ($(GCC_VER),2.96)
|
||||
CCFLAGS_TOP += -D__STL_PTHREADS
|
||||
CCFLAGS_TOP += -fmessage-length=0
|
||||
endif
|
||||
|
||||
CCFLAGS_TOP += -fno-rtti
|
||||
|
||||
LIB_TARGET_LIBS += -lpthread
|
||||
|
||||
endif
|
||||
|
||||
ifeq ($(NDB_OS),WIN32)
|
||||
ifeq (RELEASE, $(NDB_VERSION))
|
||||
CCFLAGS_WIN += /MT /GR /GS /Zi -D_WINDOWS -D_USRDLL -DNDBODBC_EXPORTS -DNO_COMMAND_HANDLER -D_MBCS -D_WINDLL -U_LIB
|
||||
else
|
||||
ifeq (RELEASE_TRACE, $(NDB_VERSION))
|
||||
CCFLAGS_WIN += /MT /GR /GS /Zi -D_WINDOWS -D_USRDLL -DNDBODBC_EXPORTS -DNO_COMMAND_HANDLER -D_MBCS -D_WINDLL -U_LIB
|
||||
else
|
||||
CCFLAGS_WIN += /MT /GR /GS /Zi -D_WINDOWS -D_USRDLL -DNDBODBC_EXPORTS -DNO_COMMAND_HANDLER -D_MBCS -D_WINDLL -U_LIB
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
|
||||
CCFLAGS_TOP += -DYYDEBUG=0 -fexceptions
|
||||
|
||||
CCFLAGS_TOP += -DHAVE_LONG_LONG
|
@@ -1,75 +0,0 @@
|
||||
include .defs.mk
|
||||
|
||||
TYPE = *
|
||||
|
||||
A_LIB = N
|
||||
PIC_LIB = Y
|
||||
SO_LIB = Y
|
||||
|
||||
LIB_TARGET = NDB_ODBC
|
||||
|
||||
LIB_TARGET_ARCHIVES = $(LIB_DIRS:%=odbc%) NDB_API
|
||||
|
||||
# Overide Defs.mk
|
||||
LDFLAGS_LAST = -lstdc++ -lm
|
||||
|
||||
XXX = \
|
||||
ndbapi \
|
||||
mgmsrvcommon \
|
||||
transporter \
|
||||
general \
|
||||
signaldataprint \
|
||||
portlib \
|
||||
logger \
|
||||
trace
|
||||
|
||||
ifeq ($(NDB_OS),WIN32)
|
||||
|
||||
LIB_DIRS = \
|
||||
handles \
|
||||
dictionary \
|
||||
codegen \
|
||||
executor \
|
||||
common
|
||||
|
||||
SOURCES += NdbOdbc.cpp
|
||||
CFLAGS_NdbOdbc.cpp += -I. -I$(call fixpath,driver)
|
||||
|
||||
PIC_ARCHIVE := Y
|
||||
NONPIC_ARCHIVE := N
|
||||
ARCHIVE_TARGET := ndb_odbcwin32
|
||||
LIB_TARGET_ARCHIVES += ndb_odbcwin32
|
||||
|
||||
ifeq (RELEASE, $(NDB_VERSION))
|
||||
WIN_LIBS += /VERSION:2.0x /NODEFAULTLIB:"odbc32" /INCREMENTAL:NO /DLL /SUBSYSTEM:WINDOWS /MACHINE:IX86 /OPT:REF /OPT:ICF /DEF:NdbOdbc.def odbc32.lib odbccp32.lib user32.lib
|
||||
else
|
||||
ifeq (RELEASE_TRACE, $(NDB_VERSION))
|
||||
WIN_LIBS += /VERSION:2.0x /NODEFAULTLIB:"odbc32" /INCREMENTAL:NO /DLL /SUBSYSTEM:WINDOWS /MACHINE:IX86 /OPT:REF /OPT:ICF /DEF:NdbOdbc.def odbc32.lib odbccp32.lib user32.lib
|
||||
else
|
||||
WIN_LIBS += /VERSION:2.0x /NODEFAULTLIB:"odbc32" /INCREMENTAL /DLL /DEBUG /SUBSYSTEM:WINDOWS /MACHINE:IX86 /DEF:NdbOdbc.def odbc32.lib odbccp32.lib user32.lib
|
||||
endif
|
||||
endif
|
||||
|
||||
else
|
||||
|
||||
LIB_DIRS = \
|
||||
driver \
|
||||
handles \
|
||||
dictionary \
|
||||
codegen \
|
||||
executor \
|
||||
common
|
||||
|
||||
endif
|
||||
|
||||
include Extra.mk
|
||||
include $(NDB_TOP)/Epilogue.mk
|
||||
|
||||
# yo
|
||||
|
||||
test:
|
||||
$(MAKE) -j4
|
||||
$(MAKE) -C $(NDB_TOP)/tools/ndbsql
|
||||
$(MAKE) -C $(NDB_TOP)/test/odbc/driver tidy
|
||||
$(MAKE) -C $(NDB_TOP)/test/odbc/driver
|
||||
$(MAKE) -C $(NDB_TOP)/test/ndbapi/testOIBasic
|
@@ -1,78 +0,0 @@
|
||||
/* Copyright (C) 2003 MySQL AB
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||
|
||||
|
||||
#include <NdbUnistd.h>
|
||||
#include <odbcinst.h>
|
||||
|
||||
#include "driver.cpp"
|
||||
|
||||
|
||||
BOOL APIENTRY DllMain( HANDLE hModule,
|
||||
DWORD ul_reason_for_call,
|
||||
LPVOID lpReserved
|
||||
)
|
||||
{
|
||||
switch (ul_reason_for_call)
|
||||
{
|
||||
case DLL_PROCESS_ATTACH:
|
||||
case DLL_THREAD_ATTACH:
|
||||
case DLL_THREAD_DETACH:
|
||||
case DLL_PROCESS_DETACH:
|
||||
break;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
BOOL INSTAPI ConfigDSN(
|
||||
HWND hwndParent,
|
||||
WORD fRequest,
|
||||
LPCSTR lpszDriver,
|
||||
LPCSTR lpszAttributes)
|
||||
{
|
||||
const char* szDSN = "NDB";
|
||||
|
||||
switch(fRequest)
|
||||
{
|
||||
case ODBC_ADD_DSN:
|
||||
SQLWriteDSNToIni(szDSN, lpszDriver);
|
||||
break;
|
||||
|
||||
case ODBC_CONFIG_DSN:
|
||||
break;
|
||||
|
||||
case ODBC_REMOVE_DSN:
|
||||
SQLRemoveDSNFromIni(szDSN);
|
||||
break;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
int FAR PASCAL
|
||||
DriverConnectProc(HWND hdlg, WORD wMsg, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
void __declspec( dllexport) FAR PASCAL LoadByOrdinal(void);
|
||||
/* Entry point to cause DM to load using ordinals */
|
||||
void __declspec( dllexport) FAR PASCAL LoadByOrdinal(void)
|
||||
{
|
||||
}
|
||||
|
@@ -1,85 +0,0 @@
|
||||
LIBRARY NdbOdbc.DLL
|
||||
VERSION 03.51.00
|
||||
EXPORTS
|
||||
SQLAllocConnect
|
||||
SQLAllocEnv
|
||||
SQLAllocHandle
|
||||
SQLAllocHandleStd
|
||||
SQLAllocStmt
|
||||
SQLBindCol
|
||||
SQLBindParam
|
||||
SQLBindParameter
|
||||
SQLBrowseConnect
|
||||
SQLBulkOperations
|
||||
SQLCancel
|
||||
SQLCloseCursor
|
||||
SQLColAttribute
|
||||
SQLColAttributes
|
||||
SQLColumnPrivileges
|
||||
SQLColumns
|
||||
SQLConnect
|
||||
SQLCopyDesc
|
||||
SQLDataSources
|
||||
SQLDescribeCol
|
||||
SQLDescribeParam
|
||||
SQLDisconnect
|
||||
SQLDriverConnect
|
||||
SQLDrivers
|
||||
SQLEndTran
|
||||
SQLError
|
||||
SQLExecDirect
|
||||
SQLExecute
|
||||
SQLExtendedFetch
|
||||
SQLFetch
|
||||
SQLFetchScroll
|
||||
SQLForeignKeys
|
||||
SQLFreeConnect
|
||||
SQLFreeEnv
|
||||
SQLFreeHandle
|
||||
SQLFreeStmt
|
||||
SQLGetConnectAttr
|
||||
SQLGetConnectOption
|
||||
SQLGetCursorName
|
||||
SQLGetData
|
||||
SQLGetDescField
|
||||
SQLGetDescRec
|
||||
SQLGetDiagField
|
||||
SQLGetDiagRec
|
||||
SQLGetEnvAttr
|
||||
SQLGetFunctions
|
||||
SQLGetInfo
|
||||
SQLGetStmtAttr
|
||||
SQLGetStmtOption
|
||||
SQLGetTypeInfo
|
||||
SQLMoreResults
|
||||
SQLNativeSql
|
||||
SQLNumParams
|
||||
SQLNumResultCols
|
||||
SQLParamData
|
||||
SQLParamOptions
|
||||
SQLPrepare
|
||||
SQLPrimaryKeys
|
||||
SQLProcedureColumns
|
||||
SQLProcedures
|
||||
SQLPutData
|
||||
SQLRowCount
|
||||
SQLSetConnectAttr
|
||||
SQLSetConnectOption
|
||||
SQLSetCursorName
|
||||
SQLSetDescField
|
||||
SQLSetDescRec
|
||||
SQLSetEnvAttr
|
||||
SQLSetParam
|
||||
SQLSetPos
|
||||
SQLSetScrollOptions
|
||||
SQLSetStmtAttr
|
||||
SQLSetStmtOption
|
||||
SQLSpecialColumns
|
||||
SQLStatistics
|
||||
SQLTablePrivileges
|
||||
SQLTables
|
||||
SQLTransact
|
||||
DllMain
|
||||
DriverConnectProc
|
||||
ConfigDSN
|
||||
LoadByOrdinal
|
@@ -1,229 +0,0 @@
|
||||
/* Copyright (C) 2003 MySQL AB
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||
|
||||
#include <common/StmtArea.hpp>
|
||||
#include <common/CodeTree.hpp>
|
||||
#include <executor/Executor.hpp>
|
||||
#include "CodeGen.hpp"
|
||||
#include "Code_root.hpp"
|
||||
|
||||
#include <FlexLexer.h>
|
||||
#include "SimpleParser.hpp"
|
||||
|
||||
void
|
||||
CodeGen::prepare(Ctx& ctx)
|
||||
{
|
||||
parse(ctx);
|
||||
if (! ctx.ok())
|
||||
return;
|
||||
analyze(ctx);
|
||||
if (! ctx.ok())
|
||||
return;
|
||||
describe(ctx);
|
||||
}
|
||||
|
||||
void
|
||||
CodeGen::execute(Ctx& ctx)
|
||||
{
|
||||
DescArea& ipd = m_stmtArea.descArea(Desc_usage_IPD);
|
||||
if (m_stmtArea.m_unbound) {
|
||||
analyze(ctx);
|
||||
if (! ctx.ok())
|
||||
return;
|
||||
describe(ctx);
|
||||
if (! ctx.ok())
|
||||
return;
|
||||
if (m_stmtArea.m_unbound) {
|
||||
ctx.pushStatus(Sqlstate::_HY010, Error::Gen, "%u input parameters have unbound SQL type", m_stmtArea.m_unbound);
|
||||
return;
|
||||
}
|
||||
ipd.setBound(true);
|
||||
}
|
||||
if (! ipd.isBound()) {
|
||||
ctx_log2(("IPD changed between executes - reanalyze"));
|
||||
// jdbc can change parameter length at each execute
|
||||
analyze(ctx);
|
||||
if (! ctx.ok())
|
||||
return;
|
||||
describe(ctx);
|
||||
if (! ctx.ok())
|
||||
return;
|
||||
freeExec(ctx);
|
||||
codegen(ctx);
|
||||
if (! ctx.ok())
|
||||
return;
|
||||
alloc(ctx);
|
||||
if (! ctx.ok())
|
||||
return;
|
||||
ipd.setBound(true);
|
||||
}
|
||||
if (m_stmtArea.m_execTree == 0) {
|
||||
codegen(ctx);
|
||||
if (! ctx.ok())
|
||||
return;
|
||||
alloc(ctx);
|
||||
if (! ctx.ok())
|
||||
return;
|
||||
}
|
||||
Executor executor(m_stmtArea);
|
||||
executor.execute(ctx);
|
||||
}
|
||||
|
||||
void
|
||||
CodeGen::fetch(Ctx& ctx)
|
||||
{
|
||||
// XXX parameter types are not checked any more
|
||||
ctx_assert(! m_stmtArea.m_unbound);
|
||||
Executor executor(m_stmtArea);
|
||||
executor.fetch(ctx);
|
||||
}
|
||||
|
||||
void
|
||||
CodeGen::parse(Ctx& ctx)
|
||||
{
|
||||
Plan_root* planRoot = new Plan_root(m_stmtArea);
|
||||
SimpleParser simpleParser(ctx, m_stmtArea, planRoot);
|
||||
simpleParser.yyparse();
|
||||
if (! ctx.ok())
|
||||
return;
|
||||
planRoot->m_paramList.resize(1 + simpleParser.paramNumber());
|
||||
ctx_log2(("CodeGen: parse done - plan tree follows"));
|
||||
if (ctx.logLevel() >= 2)
|
||||
planRoot->print(ctx);
|
||||
m_stmtArea.m_planTree = planRoot;
|
||||
}
|
||||
|
||||
void
|
||||
CodeGen::analyze(Ctx& ctx)
|
||||
{
|
||||
Plan_root* planRoot = static_cast<Plan_root*>(m_stmtArea.m_planTree);
|
||||
ctx_assert(planRoot != 0);
|
||||
Plan_base::Ctl ctl(0);
|
||||
planRoot->analyze(ctx, ctl); // returns itself
|
||||
if (! ctx.ok())
|
||||
return;
|
||||
ctx_log2(("CodeGen: analyze done - plan tree follows"));
|
||||
if (ctx.logLevel() >= 2)
|
||||
planRoot->print(ctx);
|
||||
}
|
||||
|
||||
void
|
||||
CodeGen::describe(Ctx& ctx)
|
||||
{
|
||||
Plan_root* planRoot = static_cast<Plan_root*>(m_stmtArea.m_planTree);
|
||||
ctx_assert(planRoot != 0);
|
||||
planRoot->describe(ctx);
|
||||
ctx_log2(("CodeGen: describe done"));
|
||||
}
|
||||
|
||||
void
|
||||
CodeGen::codegen(Ctx& ctx)
|
||||
{
|
||||
Plan_root* planRoot = static_cast<Plan_root*>(m_stmtArea.m_planTree);
|
||||
ctx_assert(planRoot != 0);
|
||||
Plan_base::Ctl ctl(0);
|
||||
Exec_root* execRoot = static_cast<Exec_root*>(planRoot->codegen(ctx, ctl));
|
||||
if (! ctx.ok())
|
||||
return;
|
||||
ctx_assert(execRoot != 0);
|
||||
ctx_log2(("CodeGen: codegen done - code tree follows"));
|
||||
if (ctx.logLevel() >= 2)
|
||||
execRoot->print(ctx);
|
||||
m_stmtArea.m_execTree = execRoot;
|
||||
}
|
||||
|
||||
void
|
||||
CodeGen::alloc(Ctx& ctx)
|
||||
{
|
||||
Exec_root* execRoot = static_cast<Exec_root*>(m_stmtArea.m_execTree);
|
||||
ctx_assert(execRoot != 0);
|
||||
Exec_base::Ctl ctl(0);
|
||||
execRoot->alloc(ctx, ctl);
|
||||
if (! ctx.ok())
|
||||
return;
|
||||
ctx_log2(("CodeGen: alloc done"));
|
||||
}
|
||||
|
||||
void
|
||||
CodeGen::close(Ctx& ctx)
|
||||
{
|
||||
Exec_root* execRoot = static_cast<Exec_root*>(m_stmtArea.m_execTree);
|
||||
if (execRoot != 0) {
|
||||
execRoot->close(ctx);
|
||||
ctx_log2(("CodeGen: close done"));
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
CodeGen::free(Ctx& ctx)
|
||||
{
|
||||
freePlan(ctx);
|
||||
freeExec(ctx);
|
||||
}
|
||||
|
||||
void
|
||||
CodeGen::freePlan(Ctx & ctx)
|
||||
{
|
||||
if (m_stmtArea.m_planTree != 0) {
|
||||
Plan_root* planRoot = static_cast<Plan_root*>(m_stmtArea.m_planTree);
|
||||
ctx_assert(planRoot != 0);
|
||||
unsigned count = 1 + planRoot->m_nodeList.size();
|
||||
planRoot->freeNodeList();
|
||||
delete planRoot;
|
||||
m_stmtArea.m_planTree = 0;
|
||||
ctx_log3(("CodeGen: freed %u plan tree nodes", count));
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
CodeGen::freeExec(Ctx & ctx)
|
||||
{
|
||||
if (m_stmtArea.m_execTree != 0) {
|
||||
Exec_root* execRoot = static_cast<Exec_root*>(m_stmtArea.m_execTree);
|
||||
ctx_assert(execRoot != 0);
|
||||
unsigned count = 1 + execRoot->m_nodeList.size();
|
||||
execRoot->freeNodeList();
|
||||
delete execRoot;
|
||||
m_stmtArea.m_execTree = 0;
|
||||
ctx_log3(("CodeGen: freed %u exec tree nodes", count));
|
||||
}
|
||||
}
|
||||
|
||||
// odbc support
|
||||
|
||||
void
|
||||
CodeGen::sqlGetData(Ctx& ctx, SQLUSMALLINT columnNumber, SQLSMALLINT targetType, SQLPOINTER targetValue, SQLINTEGER bufferLength, SQLINTEGER* strlen_or_Ind)
|
||||
{
|
||||
Exec_root* execRoot = static_cast<Exec_root*>(m_stmtArea.m_execTree);
|
||||
ctx_assert(execRoot != 0);
|
||||
execRoot->sqlGetData(ctx, columnNumber, targetType, targetValue, bufferLength, strlen_or_Ind);
|
||||
}
|
||||
|
||||
void
|
||||
CodeGen::sqlParamData(Ctx& ctx, SQLPOINTER* value)
|
||||
{
|
||||
Exec_root* execRoot = static_cast<Exec_root*>(m_stmtArea.m_execTree);
|
||||
ctx_assert(execRoot != 0);
|
||||
execRoot->sqlParamData(ctx, value);
|
||||
}
|
||||
|
||||
void
|
||||
CodeGen::sqlPutData(Ctx& ctx, SQLPOINTER data, SQLINTEGER strlen_or_Ind)
|
||||
{
|
||||
Exec_root* execRoot = static_cast<Exec_root*>(m_stmtArea.m_execTree);
|
||||
ctx_assert(execRoot != 0);
|
||||
execRoot->sqlPutData(ctx, data, strlen_or_Ind);
|
||||
}
|
@@ -1,69 +0,0 @@
|
||||
/* Copyright (C) 2003 MySQL AB
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||
|
||||
#ifndef ODBC_CODEGEN_CodeGen_hpp
|
||||
#define ODBC_CODEGEN_CodeGen_hpp
|
||||
|
||||
#include <common/common.hpp>
|
||||
|
||||
class StmtArea;
|
||||
class SqlField;
|
||||
class ExtField;
|
||||
|
||||
/**
|
||||
* @class CodeGen
|
||||
* @brief Compiles SQL text into ExecTree::Code
|
||||
*/
|
||||
class CodeGen {
|
||||
public:
|
||||
CodeGen(StmtArea& stmtArea);
|
||||
~CodeGen();
|
||||
// parse and analyze SQL statement
|
||||
void prepare(Ctx& ctx);
|
||||
// these are passed to Executor
|
||||
void execute(Ctx& ctx);
|
||||
void fetch(Ctx& ctx);
|
||||
// close statement (mainly scan)
|
||||
void close(Ctx& ctx);
|
||||
// free data structures
|
||||
void free(Ctx& ctx);
|
||||
// odbc support
|
||||
void sqlGetData(Ctx& ctx, SQLUSMALLINT columnNumber, SQLSMALLINT targetType, SQLPOINTER targetValue, SQLINTEGER bufferLength, SQLINTEGER* strlen_or_Ind);
|
||||
void sqlParamData(Ctx& ctx, SQLPOINTER* value);
|
||||
void sqlPutData(Ctx& ctx, SQLPOINTER data, SQLINTEGER strlen_or_Ind);
|
||||
private:
|
||||
void parse(Ctx& ctx);
|
||||
void analyze(Ctx& ctx);
|
||||
void describe(Ctx& ctx);
|
||||
void codegen(Ctx& ctx);
|
||||
void alloc(Ctx& ctx);
|
||||
void freePlan(Ctx& ctx);
|
||||
void freeExec(Ctx& ctx);
|
||||
StmtArea& m_stmtArea;
|
||||
};
|
||||
|
||||
inline
|
||||
CodeGen::CodeGen(StmtArea& stmtArea) :
|
||||
m_stmtArea(stmtArea)
|
||||
{
|
||||
}
|
||||
|
||||
inline
|
||||
CodeGen::~CodeGen()
|
||||
{
|
||||
}
|
||||
|
||||
#endif
|
@@ -1,167 +0,0 @@
|
||||
/* Copyright (C) 2003 MySQL AB
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||
|
||||
#include <common/StmtArea.hpp>
|
||||
#include "Code_base.hpp"
|
||||
#include "Code_root.hpp"
|
||||
|
||||
// Plan_base
|
||||
|
||||
Plan_base::~Plan_base()
|
||||
{
|
||||
}
|
||||
|
||||
StmtArea&
|
||||
Plan_base::stmtArea() const
|
||||
{
|
||||
ctx_assert(m_root != 0);
|
||||
return m_root->m_stmtArea;
|
||||
}
|
||||
|
||||
DescArea&
|
||||
Plan_base::descArea(DescUsage u) const
|
||||
{
|
||||
return stmtArea().descArea(u);
|
||||
}
|
||||
|
||||
ConnArea&
|
||||
Plan_base::connArea() const
|
||||
{
|
||||
return stmtArea().connArea();
|
||||
}
|
||||
|
||||
DictCatalog&
|
||||
Plan_base::dictCatalog() const
|
||||
{
|
||||
return connArea().dictCatalog();
|
||||
}
|
||||
|
||||
DictSchema&
|
||||
Plan_base::dictSchema() const
|
||||
{
|
||||
return connArea().dictSchema();
|
||||
}
|
||||
|
||||
Ndb*
|
||||
Plan_base::ndbObject() const
|
||||
{
|
||||
Ndb* ndb = connArea().ndbObject();
|
||||
ctx_assert(ndb != 0);
|
||||
return ndb;
|
||||
}
|
||||
|
||||
NdbSchemaCon*
|
||||
Plan_base::ndbSchemaCon() const
|
||||
{
|
||||
NdbSchemaCon* ndbSchemaCon = connArea().ndbSchemaCon();
|
||||
ctx_assert(ndbSchemaCon != 0);
|
||||
return ndbSchemaCon;
|
||||
}
|
||||
|
||||
NdbConnection*
|
||||
Plan_base::ndbConnection() const
|
||||
{
|
||||
NdbConnection* ndbConnection = connArea().ndbConnection();
|
||||
ctx_assert(ndbConnection != 0);
|
||||
return ndbConnection;
|
||||
}
|
||||
|
||||
void
|
||||
Plan_base::printList(Ctx& ctx, Plan_base* a[], unsigned n)
|
||||
{
|
||||
for (unsigned i = 0; i < n; i++) {
|
||||
if (a[i] == 0)
|
||||
ctx.print(" -");
|
||||
else
|
||||
a[i]->print(ctx);
|
||||
}
|
||||
}
|
||||
|
||||
// Exec_base
|
||||
|
||||
Exec_base::Code::~Code()
|
||||
{
|
||||
}
|
||||
|
||||
Exec_base::Data::~Data()
|
||||
{
|
||||
}
|
||||
|
||||
Exec_base::~Exec_base()
|
||||
{
|
||||
delete m_code; // remove when code becomes shared
|
||||
m_code = 0;
|
||||
delete m_data;
|
||||
m_data = 0;
|
||||
}
|
||||
|
||||
StmtArea&
|
||||
Exec_base::stmtArea() const
|
||||
{
|
||||
ctx_assert(m_root != 0);
|
||||
return m_root->m_stmtArea;
|
||||
}
|
||||
|
||||
DescArea&
|
||||
Exec_base::descArea(DescUsage u) const
|
||||
{
|
||||
return stmtArea().descArea(u);
|
||||
}
|
||||
|
||||
ConnArea&
|
||||
Exec_base::connArea() const
|
||||
{
|
||||
return stmtArea().connArea();
|
||||
}
|
||||
|
||||
DictSchema&
|
||||
Exec_base::dictSchema() const
|
||||
{
|
||||
return connArea().dictSchema();
|
||||
}
|
||||
|
||||
Ndb*
|
||||
Exec_base::ndbObject() const
|
||||
{
|
||||
Ndb* ndb = connArea().ndbObject();
|
||||
ctx_assert(ndb != 0);
|
||||
return ndb;
|
||||
}
|
||||
|
||||
NdbSchemaCon*
|
||||
Exec_base::ndbSchemaCon() const
|
||||
{
|
||||
NdbSchemaCon* ndbSchemaCon = connArea().ndbSchemaCon();
|
||||
ctx_assert(ndbSchemaCon != 0);
|
||||
return ndbSchemaCon;
|
||||
}
|
||||
|
||||
NdbConnection*
|
||||
Exec_base::ndbConnection() const
|
||||
{
|
||||
NdbConnection* ndbConnection = connArea().ndbConnection();
|
||||
ctx_assert(ndbConnection != 0);
|
||||
return ndbConnection;
|
||||
}
|
||||
|
||||
void
|
||||
Exec_base::printList(Ctx& ctx, Exec_base* a[], unsigned n)
|
||||
{
|
||||
for (unsigned i = 0; i < n; i++) {
|
||||
ctx_assert(a[i] != 0);
|
||||
a[i]->print(ctx);
|
||||
}
|
||||
}
|
@@ -1,237 +0,0 @@
|
||||
/* Copyright (C) 2003 MySQL AB
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||
|
||||
#ifndef ODBC_CODEGEN_Code_base_hpp
|
||||
#define ODBC_CODEGEN_Code_base_hpp
|
||||
|
||||
#include <set>
|
||||
#include <list>
|
||||
#include <vector>
|
||||
#include <common/common.hpp>
|
||||
#include <common/CodeTree.hpp>
|
||||
#include <common/DescArea.hpp>
|
||||
|
||||
class Ctx;
|
||||
class ConnArea;
|
||||
class StmtArea;
|
||||
class DescArea;
|
||||
class DictCatalog;
|
||||
class DictSchema;
|
||||
class ResultArea;
|
||||
class ResultSet;
|
||||
class SpecRow;
|
||||
class Ndb;
|
||||
class NdbSchemaCon;
|
||||
class NdbConnection;
|
||||
class NdbOperation;
|
||||
class NdbScanFilter;
|
||||
|
||||
class Plan_root;
|
||||
class Plan_table;
|
||||
class Plan_column;
|
||||
class Plan_expr;
|
||||
class Plan_expr_param;
|
||||
class Plan_pred;
|
||||
class Plan_dml_row;
|
||||
class Plan_dml_column;
|
||||
class Plan_ddl_column;
|
||||
class Plan_ddl_constr;
|
||||
class Plan_idx_column;
|
||||
class Exec_root;
|
||||
class Exec_base;
|
||||
class Exec_query;
|
||||
class Exec_expr;
|
||||
class Exec_expr_row;
|
||||
class Exec_expr_param;
|
||||
|
||||
/**
|
||||
* @class Plan_base
|
||||
* @brief Base class for plan trees
|
||||
*/
|
||||
class Plan_base : public PlanTree {
|
||||
public:
|
||||
Plan_base(Plan_root* root);
|
||||
virtual ~Plan_base() = 0;
|
||||
// get references to StmtArea via Plan_root
|
||||
StmtArea& stmtArea() const;
|
||||
DescArea& descArea(DescUsage u) const;
|
||||
ConnArea& connArea() const;
|
||||
// catalogs
|
||||
DictCatalog& dictCatalog() const;
|
||||
DictSchema& dictSchema() const;
|
||||
// ndb
|
||||
Ndb* ndbObject() const;
|
||||
NdbSchemaCon* ndbSchemaCon() const;
|
||||
NdbConnection* ndbConnection() const;
|
||||
// containers for Plan classes
|
||||
typedef std::vector<Plan_table*> TableVector;
|
||||
typedef std::vector<Plan_column*> ColumnVector;
|
||||
typedef std::vector<Plan_dml_column*> DmlColumnVector;
|
||||
typedef std::vector<Plan_ddl_column*> DdlColumnVector;
|
||||
typedef std::vector<Plan_ddl_constr*> DdlConstrVector;
|
||||
typedef std::vector<Plan_idx_column*> IdxColumnVector;
|
||||
typedef std::vector<Plan_expr*> ExprVector;
|
||||
typedef std::list<Plan_expr*> ExprList;
|
||||
typedef std::vector<ExprList> ExprListVector;
|
||||
typedef std::list<Plan_pred*> PredList;
|
||||
typedef std::set<Plan_table*> TableSet;
|
||||
typedef std::vector<Plan_expr_param*> ParamVector;
|
||||
// control area on the stack XXX needs to be designed
|
||||
struct Ctl {
|
||||
Ctl(Ctl* up);
|
||||
Ctl* m_up; // up the stack
|
||||
// analyze
|
||||
TableVector m_tableList; // resolve column names
|
||||
bool m_topand; // in top-level where clause
|
||||
bool m_extra; // anything but single pk=expr
|
||||
bool m_aggrok; // aggregate allowed
|
||||
bool m_aggrin; // within aggregate args
|
||||
bool m_const; // only constants in set clause
|
||||
PredList m_topcomp; // top level comparisons
|
||||
Plan_dml_row *m_dmlRow; // row type to convert to
|
||||
Plan_table* m_topTable; // top level table for interpreted progs
|
||||
bool m_having; // in having-predicate
|
||||
// codegen
|
||||
Exec_root* m_execRoot; // root of Exec tree
|
||||
const Exec_query* m_execQuery; // pass to column
|
||||
};
|
||||
// semantic analysis and optimization
|
||||
virtual Plan_base* analyze(Ctx& ctx, Ctl& ctl) = 0;
|
||||
// generate "executable" code
|
||||
virtual Exec_base* codegen(Ctx& ctx, Ctl& ctl) = 0;
|
||||
// misc
|
||||
virtual void print(Ctx& ctx) = 0;
|
||||
protected:
|
||||
Plan_root* m_root;
|
||||
void printList(Ctx& ctx, Plan_base* a[], unsigned n);
|
||||
};
|
||||
|
||||
inline
|
||||
Plan_base::Plan_base(Plan_root* root) :
|
||||
m_root(root)
|
||||
{
|
||||
ctx_assert(m_root != 0);
|
||||
}
|
||||
|
||||
inline
|
||||
Plan_base::Ctl::Ctl(Ctl* up) :
|
||||
m_up(up),
|
||||
m_tableList(1), // 1-based
|
||||
m_topand(false),
|
||||
m_extra(false),
|
||||
m_aggrok(false),
|
||||
m_aggrin(false),
|
||||
m_dmlRow(0),
|
||||
m_topTable(0),
|
||||
m_having(false),
|
||||
m_execRoot(0),
|
||||
m_execQuery(0)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @class Exec_base
|
||||
* @brief Base class for exec trees
|
||||
*/
|
||||
class Exec_base : public ExecTree {
|
||||
public:
|
||||
class Code : public ExecTree::Code {
|
||||
public:
|
||||
virtual ~Code() = 0;
|
||||
};
|
||||
class Data : public ExecTree::Data {
|
||||
public:
|
||||
virtual ~Data() = 0;
|
||||
};
|
||||
Exec_base(Exec_root* root);
|
||||
virtual ~Exec_base() = 0;
|
||||
// get references to StmtArea via Exec_root
|
||||
virtual StmtArea& stmtArea() const;
|
||||
DescArea& descArea(DescUsage u) const;
|
||||
ConnArea& connArea() const;
|
||||
// catalogs
|
||||
DictSchema& dictSchema() const;
|
||||
// ndb
|
||||
Ndb* ndbObject() const;
|
||||
NdbSchemaCon* ndbSchemaCon() const;
|
||||
NdbConnection* ndbConnection() const;
|
||||
// containers for Exec classes
|
||||
typedef std::vector<Exec_expr*> ExprVector;
|
||||
typedef std::vector<Exec_expr_param*> ParamVector;
|
||||
// control area on the stack
|
||||
struct Ctl {
|
||||
Ctl(Ctl* up);
|
||||
Ctl* m_up; // up the stack
|
||||
const Exec_query* m_query; // pass Data
|
||||
ExprVector m_exprList; // pass Data
|
||||
NdbOperation* m_scanOp; // scan operation
|
||||
bool m_postEval; // for rownum
|
||||
unsigned m_groupIndex; // for group by
|
||||
bool m_groupInit; // first in group
|
||||
Exec_expr_row* m_sortRow; // from sort to group by
|
||||
NdbScanFilter* m_scanFilter; // scan filter
|
||||
};
|
||||
// allocate and deallocate Data instances
|
||||
virtual void alloc(Ctx& ctx, Ctl& ctl) = 0;
|
||||
virtual void close(Ctx& ctx) = 0;
|
||||
// set Code and Data
|
||||
void setCode(const Code& code);
|
||||
void setData(Data& data);
|
||||
// misc
|
||||
virtual void print(Ctx& ctx) = 0;
|
||||
protected:
|
||||
const Code* m_code;
|
||||
Data* m_data;
|
||||
Exec_root* m_root;
|
||||
void printList(Ctx& ctx, Exec_base* a[], unsigned n);
|
||||
};
|
||||
|
||||
inline
|
||||
Exec_base::Exec_base(Exec_root* root) :
|
||||
m_code(0),
|
||||
m_data(0),
|
||||
m_root(root)
|
||||
{
|
||||
ctx_assert(m_root != 0);
|
||||
}
|
||||
|
||||
inline void
|
||||
Exec_base::setCode(const Code& code)
|
||||
{
|
||||
ctx_assert(m_code == 0);
|
||||
m_code = &code;
|
||||
}
|
||||
|
||||
inline void
|
||||
Exec_base::setData(Data& data)
|
||||
{
|
||||
ctx_assert(m_data == 0);
|
||||
m_data = &data;
|
||||
}
|
||||
|
||||
inline
|
||||
Exec_base::Ctl::Ctl(Ctl* up) :
|
||||
m_up(up),
|
||||
m_scanOp(0),
|
||||
m_postEval(false),
|
||||
m_groupIndex(0),
|
||||
m_groupInit(false),
|
||||
m_sortRow(0),
|
||||
m_scanFilter(0)
|
||||
{
|
||||
}
|
||||
|
||||
#endif
|
@@ -1,72 +0,0 @@
|
||||
/* Copyright (C) 2003 MySQL AB
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||
|
||||
#include <NdbApi.hpp>
|
||||
#include <common/StmtArea.hpp>
|
||||
#include <dictionary/DictSchema.hpp>
|
||||
#include <dictionary/DictColumn.hpp>
|
||||
#include "Code_column.hpp"
|
||||
#include "Code_table_list.hpp"
|
||||
#include "Code_table.hpp"
|
||||
|
||||
// Plan_column
|
||||
|
||||
Plan_column::~Plan_column()
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
Plan_column::analyzeColumn(Ctx& ctx, Plan_base::Ctl& ctl)
|
||||
{
|
||||
if (m_resTable != 0) // done on previous pass
|
||||
return;
|
||||
if (! (ctl.m_tableList.size() > 1)) {
|
||||
ctx.pushStatus(Sqlstate::_42000, Error::Gen, "column %s not allowed here", getPrintName());
|
||||
return;
|
||||
}
|
||||
unsigned resCount = 0;
|
||||
for (unsigned i = 1; i < ctl.m_tableList.size(); i++) {
|
||||
Plan_table* table = ctl.m_tableList[i];
|
||||
ctx_assert(table != 0);
|
||||
int ret = table->resolveColumn(ctx, this);
|
||||
if (ret < 0)
|
||||
return;
|
||||
if (ret)
|
||||
resCount++;
|
||||
}
|
||||
if (resCount == 0) {
|
||||
// XXX try to strip "schema name" from table name
|
||||
for (unsigned i = 1; i < ctl.m_tableList.size(); i++) {
|
||||
Plan_table* table = ctl.m_tableList[i];
|
||||
ctx_assert(table != 0);
|
||||
int ret = table->resolveColumn(ctx, this, true);
|
||||
if (ret < 0)
|
||||
return;
|
||||
if (ret)
|
||||
resCount++;
|
||||
}
|
||||
}
|
||||
if (resCount == 0) {
|
||||
ctx.pushStatus(Sqlstate::_42S22, Error::Gen, "column %s not found", getPrintName());
|
||||
return;
|
||||
}
|
||||
if (resCount > 1) {
|
||||
ctx.pushStatus(Error::Gen, "column %s is ambiguous", getPrintName());
|
||||
return;
|
||||
}
|
||||
// copy SQL type
|
||||
m_sqlType = dictColumn().sqlType();
|
||||
}
|
@@ -1,122 +0,0 @@
|
||||
/* Copyright (C) 2003 MySQL AB
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||
|
||||
#ifndef ODBC_CODEGEN_Code_column_hpp
|
||||
#define ODBC_CODEGEN_Code_column_hpp
|
||||
|
||||
#include <common/common.hpp>
|
||||
#include <common/DataType.hpp>
|
||||
#include "Code_base.hpp"
|
||||
|
||||
class DictColumn;
|
||||
class Plan_table;
|
||||
|
||||
/**
|
||||
* @class Plan_column
|
||||
* @brief Abstract base class for columns
|
||||
*/
|
||||
class Plan_column {
|
||||
public:
|
||||
enum Type {
|
||||
Type_expr = 1,
|
||||
Type_dml = 2,
|
||||
Type_ddl = 3, // new columns in create table
|
||||
Type_idx = 4 // old columns in create index
|
||||
};
|
||||
Plan_column(Type type, const BaseString& name);
|
||||
virtual ~Plan_column() = 0;
|
||||
void analyzeColumn(Ctx& ctx, Plan_base::Ctl& ctl);
|
||||
// attributes
|
||||
const BaseString& getName() const;
|
||||
const BaseString& getCname() const;
|
||||
const char* getPrintName() const;
|
||||
void setCname(const BaseString& cname);
|
||||
const DictColumn& dictColumn() const;
|
||||
const SqlType& sqlType() const;
|
||||
protected:
|
||||
friend class Plan_table;
|
||||
friend class Plan_comp_op;
|
||||
Type m_type;
|
||||
BaseString m_name;
|
||||
BaseString m_cname;
|
||||
BaseString m_printName;
|
||||
DictColumn* m_dictColumn;
|
||||
/**
|
||||
* Resolve to table and operational position (for example
|
||||
* column number in scan query).
|
||||
*/
|
||||
Plan_table* m_resTable;
|
||||
unsigned m_resPos;
|
||||
SqlType m_sqlType;
|
||||
};
|
||||
|
||||
inline
|
||||
Plan_column::Plan_column(Type type, const BaseString& name) :
|
||||
m_type(type),
|
||||
m_name(name),
|
||||
m_printName(name),
|
||||
m_dictColumn(0),
|
||||
m_resTable(0),
|
||||
m_resPos(0)
|
||||
{
|
||||
}
|
||||
|
||||
inline const BaseString&
|
||||
Plan_column::getName() const
|
||||
{
|
||||
return m_name;
|
||||
}
|
||||
|
||||
inline const BaseString&
|
||||
Plan_column::getCname() const
|
||||
{
|
||||
return m_cname;
|
||||
}
|
||||
|
||||
inline const char*
|
||||
Plan_column::getPrintName() const
|
||||
{
|
||||
return m_printName.c_str();
|
||||
}
|
||||
|
||||
inline void
|
||||
Plan_column::setCname(const BaseString& cname)
|
||||
{
|
||||
m_cname.assign(cname);
|
||||
if (m_cname.empty())
|
||||
m_printName.assign(m_name);
|
||||
else {
|
||||
m_printName.assign(m_cname);
|
||||
m_printName.append(".");
|
||||
m_printName.append(m_name);
|
||||
}
|
||||
}
|
||||
|
||||
inline const DictColumn&
|
||||
Plan_column::dictColumn() const
|
||||
{
|
||||
ctx_assert(m_dictColumn != 0);
|
||||
return *m_dictColumn;
|
||||
}
|
||||
|
||||
inline const SqlType&
|
||||
Plan_column::sqlType() const
|
||||
{
|
||||
ctx_assert(m_sqlType.type() != SqlType::Undef);
|
||||
return m_sqlType;
|
||||
}
|
||||
|
||||
#endif
|
@@ -1,485 +0,0 @@
|
||||
/* Copyright (C) 2003 MySQL AB
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||
|
||||
#include <dictionary/DictColumn.hpp>
|
||||
#include "Code_pred.hpp"
|
||||
#include "Code_comp_op.hpp"
|
||||
#include "Code_expr_conv.hpp"
|
||||
#include "Code_expr_column.hpp"
|
||||
#include "Code_table.hpp"
|
||||
#include "Code_root.hpp"
|
||||
|
||||
// Comp_op
|
||||
|
||||
const char*
|
||||
Comp_op::name() const
|
||||
{
|
||||
switch (m_opcode) {
|
||||
case Eq:
|
||||
return "=";
|
||||
case Noteq:
|
||||
return "!=";
|
||||
case Lt:
|
||||
return "<";
|
||||
case Lteq:
|
||||
return "<=";
|
||||
case Gt:
|
||||
return ">";
|
||||
case Gteq:
|
||||
return ">=";
|
||||
case Like:
|
||||
return "like";
|
||||
case Notlike:
|
||||
return "not like";
|
||||
case Isnull:
|
||||
return "is null";
|
||||
case Isnotnull:
|
||||
return "is not null";
|
||||
}
|
||||
ctx_assert(false);
|
||||
return "";
|
||||
}
|
||||
|
||||
unsigned
|
||||
Comp_op::arity() const
|
||||
{
|
||||
switch (m_opcode) {
|
||||
case Eq:
|
||||
case Noteq:
|
||||
case Lt:
|
||||
case Lteq:
|
||||
case Gt:
|
||||
case Gteq:
|
||||
case Like:
|
||||
case Notlike:
|
||||
return 2;
|
||||
case Isnull:
|
||||
case Isnotnull:
|
||||
return 1;
|
||||
}
|
||||
ctx_assert(false);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Plan_comp_op
|
||||
|
||||
Plan_comp_op::~Plan_comp_op()
|
||||
{
|
||||
}
|
||||
|
||||
Plan_base*
|
||||
Plan_comp_op::analyze(Ctx& ctx, Ctl& ctl)
|
||||
{
|
||||
m_exec = 0;
|
||||
const unsigned arity = m_op.arity();
|
||||
// analyze operands
|
||||
for (unsigned i = 1; i <= arity; i++) {
|
||||
ctx_assert(m_expr[i] != 0);
|
||||
m_expr[i]->analyze(ctx, ctl);
|
||||
if (! ctx.ok())
|
||||
return 0;
|
||||
}
|
||||
// for each operand, find type to convert to
|
||||
SqlType con[1 + 2];
|
||||
if (arity == 1) {
|
||||
const SqlType& t1 = m_expr[1]->sqlType();
|
||||
switch (t1.type()) {
|
||||
case SqlType::Char:
|
||||
case SqlType::Varchar:
|
||||
case SqlType::Smallint:
|
||||
case SqlType::Integer:
|
||||
case SqlType::Bigint:
|
||||
case SqlType::Real:
|
||||
case SqlType::Double:
|
||||
case SqlType::Datetime:
|
||||
case SqlType::Null:
|
||||
case SqlType::Unbound:
|
||||
con[1] = t1;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if (con[1].type() == SqlType::Undef) {
|
||||
char b1[40];
|
||||
t1.print(b1, sizeof(b1));
|
||||
ctx.pushStatus(Error::Gen, "type mismatch in comparison: %s %s", b1, m_op.name());
|
||||
return 0;
|
||||
}
|
||||
} else if (arity == 2) {
|
||||
const SqlType& t1 = m_expr[1]->sqlType();
|
||||
const SqlType& t2 = m_expr[2]->sqlType();
|
||||
switch (t1.type()) {
|
||||
case SqlType::Char:
|
||||
switch (t2.type()) {
|
||||
case SqlType::Char:
|
||||
case SqlType::Varchar:
|
||||
case SqlType::Null:
|
||||
con[1] = t1;
|
||||
con[2] = t2;
|
||||
break;
|
||||
case SqlType::Unbound:
|
||||
con[1] = con[2] = t2;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case SqlType::Varchar:
|
||||
switch (t2.type()) {
|
||||
case SqlType::Char:
|
||||
case SqlType::Varchar:
|
||||
case SqlType::Null:
|
||||
con[1] = t1;
|
||||
con[2] = t2;
|
||||
break;
|
||||
case SqlType::Unbound:
|
||||
con[1] = con[2] = t2;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case SqlType::Smallint:
|
||||
case SqlType::Integer:
|
||||
case SqlType::Bigint:
|
||||
switch (t2.type()) {
|
||||
case SqlType::Smallint:
|
||||
case SqlType::Integer:
|
||||
case SqlType::Bigint:
|
||||
// conversion would mask primary key optimization
|
||||
con[1] = t1;
|
||||
con[2] = t2;
|
||||
break;
|
||||
case SqlType::Real:
|
||||
case SqlType::Double:
|
||||
con[1].setType(ctx, SqlType::Double);
|
||||
con[2] = con[1];
|
||||
break;
|
||||
case SqlType::Null:
|
||||
con[1] = t1;
|
||||
con[2] = t2;
|
||||
break;
|
||||
case SqlType::Unbound:
|
||||
con[1] = con[2] = t2;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case SqlType::Real:
|
||||
case SqlType::Double:
|
||||
switch (t2.type()) {
|
||||
case SqlType::Smallint:
|
||||
case SqlType::Integer:
|
||||
case SqlType::Bigint:
|
||||
case SqlType::Real:
|
||||
case SqlType::Double:
|
||||
con[1].setType(ctx, SqlType::Double);
|
||||
con[2] = con[1];
|
||||
break;
|
||||
case SqlType::Null:
|
||||
con[1] = t1;
|
||||
con[2] = t2;
|
||||
break;
|
||||
case SqlType::Unbound:
|
||||
con[1] = con[2] = t2;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case SqlType::Datetime:
|
||||
switch (t2.type()) {
|
||||
case SqlType::Datetime:
|
||||
con[1] = t1;
|
||||
con[2] = t2;
|
||||
break;
|
||||
case SqlType::Unbound:
|
||||
con[1] = con[2] = t2;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case SqlType::Null:
|
||||
switch (t2.type()) {
|
||||
case SqlType::Char:
|
||||
case SqlType::Varchar:
|
||||
case SqlType::Smallint:
|
||||
case SqlType::Integer:
|
||||
case SqlType::Bigint:
|
||||
case SqlType::Real:
|
||||
case SqlType::Double:
|
||||
case SqlType::Datetime:
|
||||
con[1] = t1;
|
||||
con[2] = t2;
|
||||
break;
|
||||
case SqlType::Unbound:
|
||||
con[1] = con[2] = t2;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case SqlType::Unbound:
|
||||
con[1] = con[2] = t1;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if (con[1].type() == SqlType::Undef || con[2].type() == SqlType::Undef) {
|
||||
char b1[40], b2[40];
|
||||
t1.print(b1, sizeof(b1));
|
||||
t2.print(b2, sizeof(b2));
|
||||
ctx.pushStatus(Error::Gen, "type mismatch in comparison: %s %s %s", b1, m_op.name(), b2);
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
ctx_assert(false);
|
||||
return 0;
|
||||
}
|
||||
if (! ctx.ok())
|
||||
return 0;
|
||||
// insert required conversions
|
||||
for (unsigned i = 1; i <= arity; i++) {
|
||||
if (con[i].type() == SqlType::Unbound) {
|
||||
continue;
|
||||
}
|
||||
Plan_expr_conv* exprConv = new Plan_expr_conv(m_root, con[i]);
|
||||
m_root->saveNode(exprConv);
|
||||
exprConv->setExpr(m_expr[i]);
|
||||
m_expr[i] = static_cast<Plan_expr*>(exprConv->analyze(ctx, ctl));
|
||||
if (! ctx.ok())
|
||||
return 0;
|
||||
ctx_assert(m_expr[i] != 0);
|
||||
}
|
||||
// look for column=expr
|
||||
if (ctl.m_topand && m_op.m_opcode == Comp_op::Eq) {
|
||||
ctx_assert(arity == 2);
|
||||
for (unsigned i = 1, j = 2; i <= 2; i++, j--) {
|
||||
if (m_expr[i]->type() != Plan_expr::TypeColumn)
|
||||
continue;
|
||||
Plan_expr_column* column = static_cast<Plan_expr_column*>(m_expr[i]);
|
||||
if (! column->resolveEq(ctx, m_expr[j]))
|
||||
ctl.m_extra = true;
|
||||
}
|
||||
} else {
|
||||
ctl.m_extra = true;
|
||||
}
|
||||
// save top level comparison on list
|
||||
if (ctl.m_topand) {
|
||||
ctl.m_topcomp.push_back(this);
|
||||
}
|
||||
// table dependencies are union from operands
|
||||
m_tableSet.clear();
|
||||
for (unsigned i = 1; i <= arity; i++) {
|
||||
const TableSet& ts = m_expr[i]->tableSet();
|
||||
m_tableSet.insert(ts.begin(), ts.end());
|
||||
}
|
||||
// set of tables for which interpreter cannot be used
|
||||
m_noInterp.clear();
|
||||
// convenient
|
||||
#undef ustype
|
||||
#define ustype(b, n) (((b) ? 1 : 0) * 100 + (n))
|
||||
if (arity == 1) {
|
||||
for (unsigned i = 1; i <= 1; i++) {
|
||||
const SqlType t1 = m_expr[i]->sqlType();
|
||||
switch (m_op.m_opcode) {
|
||||
case Comp_op::Isnull:
|
||||
case Comp_op::Isnotnull:
|
||||
if (m_expr[i]->type() == Plan_expr::TypeColumn) {
|
||||
switch (ustype(t1.unSigned(), t1.type())) {
|
||||
// all types accepted now
|
||||
default:
|
||||
{
|
||||
Plan_expr_column* column = static_cast<Plan_expr_column*>(m_expr[i]);
|
||||
ctx_assert(column->m_resTable != 0);
|
||||
m_interpColumn[i] = column;
|
||||
continue; // ok
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
const TableSet& ts = m_expr[i]->tableSet();
|
||||
m_noInterp.insert(ts.begin(), ts.end());
|
||||
}
|
||||
} else if (arity == 2) {
|
||||
for (unsigned i = 1, j = 2; i <= 2; i++, j--) {
|
||||
const SqlType t1 = m_expr[i]->sqlType();
|
||||
switch (m_op.m_opcode) {
|
||||
case Comp_op::Like:
|
||||
case Comp_op::Notlike:
|
||||
if (i == 2) // col like val but not val like col
|
||||
break;
|
||||
/*FALLTHRU*/
|
||||
case Comp_op::Eq:
|
||||
case Comp_op::Noteq:
|
||||
case Comp_op::Lt:
|
||||
case Comp_op::Lteq:
|
||||
case Comp_op::Gt:
|
||||
case Comp_op::Gteq:
|
||||
if (m_expr[i]->type() == Plan_expr::TypeColumn) {
|
||||
switch (ustype(t1.unSigned(), t1.type())) {
|
||||
case ustype(false, SqlType::Char):
|
||||
case ustype(false, SqlType::Varchar):
|
||||
case ustype(true, SqlType::Smallint):
|
||||
case ustype(true, SqlType::Integer):
|
||||
case ustype(true, SqlType::Bigint):
|
||||
{
|
||||
Plan_expr_column* column = static_cast<Plan_expr_column*>(m_expr[i]);
|
||||
ctx_assert(column->m_resTable != 0);
|
||||
const TableSet& ts = m_expr[j]->tableSet();
|
||||
if (ts.find(column->m_resTable) == ts.end()) {
|
||||
// candidate for column=const
|
||||
m_interpColumn[i] = column;
|
||||
continue; // ok
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
const TableSet& ts = m_expr[i]->tableSet();
|
||||
m_noInterp.insert(ts.begin(), ts.end());
|
||||
}
|
||||
} else {
|
||||
ctx_assert(false);
|
||||
return 0;
|
||||
}
|
||||
#undef ustype
|
||||
return this;
|
||||
}
|
||||
|
||||
Exec_base*
|
||||
Plan_comp_op::codegen(Ctx& ctx, Ctl& ctl)
|
||||
{
|
||||
if (m_exec != 0)
|
||||
return m_exec;
|
||||
const unsigned arity = m_op.arity();
|
||||
Exec_comp_op* exec = new Exec_comp_op(ctl.m_execRoot);
|
||||
ctl.m_execRoot->saveNode(exec);
|
||||
// create code for operands
|
||||
for (unsigned i = 1; i <= arity; i++) {
|
||||
ctx_assert(m_expr[i] != 0);
|
||||
Exec_expr* execExpr = static_cast<Exec_expr*>(m_expr[i]->codegen(ctx, ctl));
|
||||
if (! ctx.ok())
|
||||
return 0;
|
||||
ctx_assert(execExpr != 0);
|
||||
exec->setExpr(i, execExpr);
|
||||
}
|
||||
// create the code
|
||||
Exec_comp_op::Code& code = *new Exec_comp_op::Code(m_op);
|
||||
// interpreted column=const
|
||||
if (! ctl.m_having) {
|
||||
ctx_assert(ctl.m_topTable != 0);
|
||||
for (unsigned i = 1; i <= arity; i++) {
|
||||
Plan_expr_column* column = m_interpColumn[i];
|
||||
if (column == 0)
|
||||
continue;
|
||||
ctx_assert(column->m_resTable != 0);
|
||||
if (column->m_resTable != ctl.m_topTable)
|
||||
continue;
|
||||
ctx_assert(code.m_interpColumn == 0);
|
||||
code.m_interpColumn = i;
|
||||
code.m_interpAttrId = column->dictColumn().getAttrId();
|
||||
ctx_log2(("can use interpreter on %s", column->getPrintName()));
|
||||
}
|
||||
}
|
||||
exec->setCode(code);
|
||||
m_exec = exec;
|
||||
return exec;
|
||||
}
|
||||
|
||||
void
|
||||
Plan_comp_op::print(Ctx& ctx)
|
||||
{
|
||||
ctx.print(" [%s", m_op.name());
|
||||
Plan_base* a[] = { m_expr[1], m_expr[2] };
|
||||
printList(ctx, a, m_op.arity());
|
||||
ctx.print("]");
|
||||
}
|
||||
|
||||
bool
|
||||
Plan_comp_op::isGroupBy(const Plan_expr_row* row) const
|
||||
{
|
||||
const unsigned arity = m_op.arity();
|
||||
for (unsigned i = 1; i <= arity; i++) {
|
||||
ctx_assert(m_expr[i] != 0);
|
||||
if (! m_expr[i]->isGroupBy(row))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// Code_comp_op
|
||||
|
||||
Exec_comp_op::Code::~Code()
|
||||
{
|
||||
}
|
||||
|
||||
Exec_comp_op::Data::~Data()
|
||||
{
|
||||
}
|
||||
|
||||
Exec_comp_op::~Exec_comp_op()
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
Exec_comp_op::alloc(Ctx& ctx, Ctl& ctl)
|
||||
{
|
||||
const Code& code = getCode();
|
||||
// allocate subexpressions
|
||||
unsigned arity = code.m_op.arity();
|
||||
for (unsigned i = 1; i <= arity; i++) {
|
||||
ctx_assert(m_expr[i] != 0);
|
||||
m_expr[i]->alloc(ctx, ctl);
|
||||
if (! ctx.ok())
|
||||
return;
|
||||
}
|
||||
Data& data = *new Data;
|
||||
setData(data);
|
||||
}
|
||||
|
||||
void
|
||||
Exec_comp_op::close(Ctx& ctx)
|
||||
{
|
||||
const Code& code = getCode();
|
||||
unsigned arity = code.m_op.arity();
|
||||
for (unsigned i = 1; i <= arity; i++) {
|
||||
ctx_assert(m_expr[i] != 0);
|
||||
m_expr[i]->close(ctx);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Exec_comp_op::print(Ctx& ctx)
|
||||
{
|
||||
const Code& code = getCode();
|
||||
ctx.print(" [%s", code.m_op.name());
|
||||
Exec_base* a[] = { m_expr[1], m_expr[2] };
|
||||
printList(ctx, a, code.m_op.arity());
|
||||
ctx.print("]");
|
||||
}
|
@@ -1,172 +0,0 @@
|
||||
/* Copyright (C) 2003 MySQL AB
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||
|
||||
#ifndef ODBC_CODEGEN_Code_comp_op_hpp
|
||||
#define ODBC_CODEGEN_Code_comp_op_hpp
|
||||
|
||||
#include <common/common.hpp>
|
||||
#include <common/DataField.hpp>
|
||||
#include "Code_pred.hpp"
|
||||
#include "Code_expr.hpp"
|
||||
#include "Code_expr_column.hpp"
|
||||
|
||||
/**
|
||||
* @class Comp_op
|
||||
* @brief Comparison operations
|
||||
*/
|
||||
struct Comp_op {
|
||||
enum Opcode {
|
||||
Eq = 1, // binary
|
||||
Noteq,
|
||||
Lt,
|
||||
Lteq,
|
||||
Gt,
|
||||
Gteq,
|
||||
Like,
|
||||
Notlike,
|
||||
Isnull, // unary
|
||||
Isnotnull
|
||||
};
|
||||
Comp_op(Opcode opcode);
|
||||
const char* name() const;
|
||||
unsigned arity() const;
|
||||
Opcode m_opcode;
|
||||
};
|
||||
|
||||
inline
|
||||
Comp_op::Comp_op(Opcode opcode) :
|
||||
m_opcode(opcode)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @class Plan_comp_op
|
||||
* @brief Comparison operator node in PlanTree
|
||||
*/
|
||||
class Plan_comp_op : public Plan_pred {
|
||||
public:
|
||||
Plan_comp_op(Plan_root* root, Comp_op op);
|
||||
virtual ~Plan_comp_op();
|
||||
void setExpr(unsigned i, Plan_expr* expr);
|
||||
Plan_base* analyze(Ctx& ctx, Ctl& ctl);
|
||||
Exec_base* codegen(Ctx& ctx, Ctl& ctl);
|
||||
void print(Ctx& ctx);
|
||||
virtual bool isGroupBy(const Plan_expr_row* row) const;
|
||||
protected:
|
||||
Comp_op m_op;
|
||||
Plan_expr* m_expr[1 + 2];
|
||||
Plan_expr_column* m_interpColumn[1 + 2]; // candidates
|
||||
};
|
||||
|
||||
inline
|
||||
Plan_comp_op::Plan_comp_op(Plan_root* root, Comp_op op) :
|
||||
Plan_pred(root, TypeComp),
|
||||
m_op(op)
|
||||
{
|
||||
m_expr[0] = m_expr[1] = m_expr[2] = 0;
|
||||
m_interpColumn[0] = m_interpColumn[1] = m_interpColumn[2] = 0;
|
||||
}
|
||||
|
||||
inline void
|
||||
Plan_comp_op::setExpr(unsigned i, Plan_expr* expr)
|
||||
{
|
||||
ctx_assert(1 <= i && i <= 2);
|
||||
m_expr[i] = expr;
|
||||
}
|
||||
|
||||
/**
|
||||
* @class Exec_comp_op
|
||||
* @brief Comparison operator node in ExecTree
|
||||
*/
|
||||
class Exec_comp_op : public Exec_pred {
|
||||
public:
|
||||
class Code : public Exec_pred::Code {
|
||||
public:
|
||||
Code(Comp_op op);
|
||||
virtual ~Code();
|
||||
protected:
|
||||
friend class Plan_comp_op;
|
||||
friend class Exec_comp_op;
|
||||
Comp_op m_op;
|
||||
unsigned m_interpColumn; // 1 or 2 if interpreted column, 0 if both constant
|
||||
NdbAttrId m_interpAttrId;
|
||||
};
|
||||
class Data : public Exec_pred::Data {
|
||||
public:
|
||||
Data();
|
||||
virtual ~Data();
|
||||
protected:
|
||||
friend class Exec_comp_op;
|
||||
};
|
||||
Exec_comp_op(Exec_root* root);
|
||||
virtual ~Exec_comp_op();
|
||||
void alloc(Ctx& ctx, Ctl& ctl);
|
||||
void execInterp(Ctx& ctx, Ctl& ctl);
|
||||
void evaluate(Ctx& ctx, Ctl& ctl);
|
||||
void close(Ctx& ctx);
|
||||
void print(Ctx& ctx);
|
||||
// children
|
||||
const Code& getCode() const;
|
||||
Data& getData() const;
|
||||
void setExpr(unsigned i, Exec_expr* expr);
|
||||
protected:
|
||||
Exec_expr* m_expr[1 + 2];
|
||||
};
|
||||
|
||||
inline
|
||||
Exec_comp_op::Code::Code(Comp_op op) :
|
||||
m_op(op),
|
||||
m_interpColumn(0),
|
||||
m_interpAttrId((NdbAttrId)-1)
|
||||
{
|
||||
}
|
||||
|
||||
inline
|
||||
Exec_comp_op::Data::Data()
|
||||
{
|
||||
}
|
||||
|
||||
inline
|
||||
Exec_comp_op::Exec_comp_op(Exec_root* root) :
|
||||
Exec_pred(root)
|
||||
{
|
||||
m_expr[0] = m_expr[1] = m_expr[2] = 0;
|
||||
}
|
||||
|
||||
// children
|
||||
|
||||
inline const Exec_comp_op::Code&
|
||||
Exec_comp_op::getCode() const
|
||||
{
|
||||
const Code* code = static_cast<const Code*>(m_code);
|
||||
return *code;
|
||||
}
|
||||
|
||||
inline Exec_comp_op::Data&
|
||||
Exec_comp_op::getData() const
|
||||
{
|
||||
Data* data = static_cast<Data*>(m_data);
|
||||
return *data;
|
||||
}
|
||||
|
||||
inline void
|
||||
Exec_comp_op::setExpr(unsigned i, Exec_expr* expr)
|
||||
{
|
||||
ctx_assert(1 <= i && i <= 2 && m_expr[i] == 0);
|
||||
m_expr[i] = expr;
|
||||
}
|
||||
|
||||
#endif
|
@@ -1,124 +0,0 @@
|
||||
/* Copyright (C) 2003 MySQL AB
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||
|
||||
#include <common/StmtArea.hpp>
|
||||
#include "Code_create_index.hpp"
|
||||
#include "Code_root.hpp"
|
||||
|
||||
// Plan_create_index
|
||||
|
||||
Plan_create_index::~Plan_create_index()
|
||||
{
|
||||
}
|
||||
|
||||
Plan_base*
|
||||
Plan_create_index::analyze(Ctx& ctx, Ctl& ctl)
|
||||
{
|
||||
stmtArea().stmtInfo().setName(Stmt_name_create_index);
|
||||
// analyze the table
|
||||
ctx_assert(m_table != 0);
|
||||
m_table->analyze(ctx, ctl);
|
||||
if (! ctx.ok())
|
||||
return 0;
|
||||
// analyze the columns
|
||||
ctl.m_tableList.resize(1 + 1); // indexed from 1
|
||||
ctl.m_tableList[1] = m_table;
|
||||
for (unsigned i = 1, n = countColumn(); i <= n; i++) {
|
||||
Plan_idx_column* column = getColumn(i);
|
||||
column->analyze(ctx, ctl);
|
||||
if (! ctx.ok())
|
||||
return 0;
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
void
|
||||
Plan_create_index::describe(Ctx& ctx)
|
||||
{
|
||||
stmtArea().setFunction(ctx, "CREATE INDEX", SQL_DIAG_CREATE_INDEX);
|
||||
}
|
||||
|
||||
Exec_base*
|
||||
Plan_create_index::codegen(Ctx& ctx, Ctl& ctl)
|
||||
{
|
||||
Exec_create_index* exec = new Exec_create_index(ctl.m_execRoot);
|
||||
ctl.m_execRoot->saveNode(exec);
|
||||
const unsigned count = countColumn();
|
||||
const char** attrList = new const char* [1 + count];
|
||||
attrList[0] = 0; // unused
|
||||
for (unsigned i = 1; i <= count; i++) {
|
||||
Plan_idx_column* column = getColumn(i);
|
||||
const char* cname = column->getName().c_str();
|
||||
attrList[i] = strcpy(new char[strlen(cname) + 1], cname);
|
||||
}
|
||||
Exec_create_index::Code& code = *new Exec_create_index::Code(m_name, m_table->getName(), m_type, count, attrList);
|
||||
exec->setCode(code);
|
||||
code.m_fragmentType = m_fragmentType;
|
||||
code.m_logging = m_logging;
|
||||
return exec;
|
||||
}
|
||||
|
||||
void
|
||||
Plan_create_index::print(Ctx& ctx)
|
||||
{
|
||||
ctx.print(" [create_index name=%s table=%s type=%d", m_name.c_str(), m_table->getName().c_str(), (int)m_type);
|
||||
ctx.print(" [");
|
||||
for (unsigned i = 1; i <= countColumn(); i++) {
|
||||
Plan_idx_column* column = getColumn(i);
|
||||
if (i > 1)
|
||||
ctx.print(" ");
|
||||
column->print(ctx);
|
||||
}
|
||||
ctx.print("]");
|
||||
}
|
||||
|
||||
// Exec_create_index
|
||||
|
||||
Exec_create_index::Code::~Code()
|
||||
{
|
||||
for (unsigned i = 1; i <= m_attrCount; i++) {
|
||||
delete[] m_attrList[i];
|
||||
m_attrList[i] = 0;
|
||||
}
|
||||
delete[] m_attrList;
|
||||
}
|
||||
|
||||
Exec_create_index::Data::~Data()
|
||||
{
|
||||
}
|
||||
|
||||
Exec_create_index::~Exec_create_index()
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
Exec_create_index::alloc(Ctx& ctx, Ctl& ctl)
|
||||
{
|
||||
Data& data = *new Data;
|
||||
setData(data);
|
||||
}
|
||||
|
||||
void
|
||||
Exec_create_index::close(Ctx& ctx)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
Exec_create_index::print(Ctx& ctx)
|
||||
{
|
||||
const Code& code = getCode();
|
||||
ctx.print(" [create_index %s]", code.m_tableName.c_str());
|
||||
}
|
@@ -1,203 +0,0 @@
|
||||
/* Copyright (C) 2003 MySQL AB
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||
|
||||
#ifndef ODBC_CODEGEN_Code_create_index_hpp
|
||||
#define ODBC_CODEGEN_Code_create_index_hpp
|
||||
|
||||
#include <vector>
|
||||
#include <NdbApi.hpp>
|
||||
#include <common/common.hpp>
|
||||
#include "Code_ddl.hpp"
|
||||
#include "Code_table.hpp"
|
||||
#include "Code_idx_column.hpp"
|
||||
|
||||
class DictTable;
|
||||
class DictColumn;
|
||||
|
||||
/**
|
||||
* @class Plan_create_index
|
||||
* @brief Create table in PlanTree
|
||||
*/
|
||||
class Plan_create_index : public Plan_ddl {
|
||||
public:
|
||||
Plan_create_index(Plan_root* root, const BaseString& name);
|
||||
virtual ~Plan_create_index();
|
||||
Plan_base* analyze(Ctx& ctx, Ctl& ctl);
|
||||
Exec_base* codegen(Ctx& ctx, Ctl& ctl);
|
||||
void describe(Ctx & ctx);
|
||||
void print(Ctx& ctx);
|
||||
// attributes
|
||||
const BaseString& getName() const;
|
||||
// children
|
||||
void setType(NdbDictionary::Object::Type type);
|
||||
void setTable(Plan_table* table);
|
||||
unsigned countColumn() const;
|
||||
void addColumn(Plan_idx_column* column);
|
||||
Plan_idx_column* getColumn(unsigned i) const;
|
||||
void setFragmentType(NdbDictionary::Object::FragmentType fragmentType);
|
||||
void setLogging(bool logging);
|
||||
protected:
|
||||
BaseString m_name;
|
||||
NdbDictionary::Object::Type m_type;
|
||||
Plan_table* m_table;
|
||||
IdxColumnVector m_columnList;
|
||||
NdbDictionary::Object::FragmentType m_fragmentType;
|
||||
bool m_logging;
|
||||
};
|
||||
|
||||
inline
|
||||
Plan_create_index::Plan_create_index(Plan_root* root, const BaseString& name) :
|
||||
Plan_ddl(root),
|
||||
m_name(name),
|
||||
m_type(NdbDictionary::Object::TypeUndefined),
|
||||
m_columnList(1),
|
||||
m_fragmentType(NdbDictionary::Object::FragUndefined),
|
||||
m_logging(true)
|
||||
{
|
||||
}
|
||||
|
||||
inline const BaseString&
|
||||
Plan_create_index::getName() const
|
||||
{
|
||||
return m_name;
|
||||
}
|
||||
|
||||
// children
|
||||
|
||||
inline void
|
||||
Plan_create_index::setType(NdbDictionary::Object::Type type)
|
||||
{
|
||||
m_type = type;
|
||||
}
|
||||
|
||||
inline void
|
||||
Plan_create_index::setTable(Plan_table* table)
|
||||
{
|
||||
ctx_assert(table != 0);
|
||||
m_table = table;
|
||||
}
|
||||
|
||||
inline unsigned
|
||||
Plan_create_index::countColumn() const
|
||||
{
|
||||
return m_columnList.size() - 1;
|
||||
}
|
||||
|
||||
inline void
|
||||
Plan_create_index::addColumn(Plan_idx_column* column)
|
||||
{
|
||||
ctx_assert(column != 0);
|
||||
m_columnList.push_back(column);
|
||||
}
|
||||
|
||||
inline Plan_idx_column*
|
||||
Plan_create_index::getColumn(unsigned i) const
|
||||
{
|
||||
ctx_assert(1 <= i && i <= countColumn() && m_columnList[i] != 0);
|
||||
return m_columnList[i];
|
||||
}
|
||||
|
||||
inline void
|
||||
Plan_create_index::setFragmentType(NdbDictionary::Object::FragmentType fragmentType)
|
||||
{
|
||||
m_fragmentType = fragmentType;
|
||||
}
|
||||
|
||||
inline void
|
||||
Plan_create_index::setLogging(bool logging)
|
||||
{
|
||||
m_logging = logging;
|
||||
}
|
||||
|
||||
/**
|
||||
* @class Exec_create_index
|
||||
* @brief Create table in ExecTree
|
||||
*/
|
||||
class Exec_create_index : public Exec_ddl {
|
||||
public:
|
||||
class Code : public Exec_ddl::Code {
|
||||
public:
|
||||
Code(const BaseString& indexName, const BaseString& tableName, NdbDictionary::Object::Type type, unsigned attrCount, const char** attrList);
|
||||
virtual ~Code();
|
||||
protected:
|
||||
friend class Plan_create_index;
|
||||
friend class Exec_create_index;
|
||||
const BaseString m_indexName;
|
||||
const BaseString m_tableName;
|
||||
NdbDictionary::Object::Type m_type;
|
||||
const unsigned m_attrCount;
|
||||
const char** m_attrList;
|
||||
NdbDictionary::Object::FragmentType m_fragmentType;
|
||||
bool m_logging;
|
||||
};
|
||||
class Data : public Exec_ddl::Data {
|
||||
public:
|
||||
Data();
|
||||
virtual ~Data();
|
||||
protected:
|
||||
friend class Exec_create_index;
|
||||
};
|
||||
Exec_create_index(Exec_root* root);
|
||||
virtual ~Exec_create_index();
|
||||
void alloc(Ctx& ctx, Ctl& ctl);
|
||||
void execute(Ctx& ctx, Ctl& ctl);
|
||||
void close(Ctx& ctx);
|
||||
void print(Ctx& ctx);
|
||||
// children
|
||||
const Code& getCode() const;
|
||||
Data& getData() const;
|
||||
};
|
||||
|
||||
inline
|
||||
Exec_create_index::Code::Code(const BaseString& indexName, const BaseString& tableName, NdbDictionary::Object::Type type, unsigned attrCount, const char** attrList) :
|
||||
m_indexName(indexName),
|
||||
m_tableName(tableName),
|
||||
m_type(type),
|
||||
m_attrCount(attrCount),
|
||||
m_attrList(attrList),
|
||||
m_fragmentType(NdbDictionary::Object::FragUndefined),
|
||||
m_logging(true)
|
||||
{
|
||||
}
|
||||
|
||||
inline
|
||||
Exec_create_index::Data::Data()
|
||||
{
|
||||
}
|
||||
|
||||
inline
|
||||
Exec_create_index::Exec_create_index(Exec_root* root) :
|
||||
Exec_ddl(root)
|
||||
{
|
||||
}
|
||||
|
||||
// children
|
||||
|
||||
inline const Exec_create_index::Code&
|
||||
Exec_create_index::getCode() const
|
||||
{
|
||||
const Code* code = static_cast<const Code*>(m_code);
|
||||
return *code;
|
||||
}
|
||||
|
||||
inline Exec_create_index::Data&
|
||||
Exec_create_index::getData() const
|
||||
{
|
||||
Data* data = static_cast<Data*>(m_data);
|
||||
return *data;
|
||||
}
|
||||
|
||||
#endif
|
@@ -1,162 +0,0 @@
|
||||
/* Copyright (C) 2003 MySQL AB
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||
|
||||
#include "Code_create_row.hpp"
|
||||
#include "Code_root.hpp"
|
||||
|
||||
Plan_create_row::~Plan_create_row()
|
||||
{
|
||||
}
|
||||
|
||||
Plan_base*
|
||||
Plan_create_row::analyze(Ctx& ctx, Ctl& ctl)
|
||||
{
|
||||
// check for duplicate column name
|
||||
for (unsigned i = 1, n = countColumn(); i < n; i++) {
|
||||
const BaseString& a = getColumn(i)->getName();
|
||||
for (unsigned i2 = i + 1; i2 <= n; i2++) {
|
||||
const BaseString& a2 = getColumn(i2)->getName();
|
||||
if (strcmp(a.c_str(), a2.c_str()) == 0) {
|
||||
ctx.pushStatus(Error::Gen, "duplicate column %s", a.c_str());
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
// move single-column primary key constraint to constraint list
|
||||
for (unsigned i = 1, n = countColumn(); i <= n; i++) {
|
||||
Plan_ddl_column* column = getColumn(i);
|
||||
if (column->m_primaryKey) {
|
||||
Plan_ddl_row* ddlRow = new Plan_ddl_row(m_root);
|
||||
m_root->saveNode(ddlRow);
|
||||
ddlRow->addColumn(column);
|
||||
Plan_ddl_constr* constr = new Plan_ddl_constr(m_root);
|
||||
m_root->saveNode(constr);
|
||||
constr->setRow(ddlRow);
|
||||
addConstr(constr);
|
||||
column->m_primaryKey = false; // will be set again
|
||||
}
|
||||
}
|
||||
// check primary key constraints
|
||||
if (countConstr() < 1) {
|
||||
ctx.pushStatus(Error::Gen, "table must have a primary key");
|
||||
return 0;
|
||||
}
|
||||
if (countConstr() > 1) {
|
||||
ctx.pushStatus(Error::Gen, "table can have only one primary key");
|
||||
return 0;
|
||||
}
|
||||
Plan_ddl_row* ddlRow = getConstr(1)->getRow();
|
||||
for (unsigned i = 1, n = ddlRow->countColumn(); i <= n; i++) {
|
||||
Plan_ddl_column* column = ddlRow->getColumn(i);
|
||||
const BaseString& a = column->getName();
|
||||
bool found = false;
|
||||
for (unsigned i2 = 1, n2 = countColumn(); i2 <= n2; i2++) {
|
||||
Plan_ddl_column* column2 = getColumn(i2);
|
||||
const BaseString& a2 = column2->getName();
|
||||
if (strcmp(a.c_str(), a2.c_str()) != 0)
|
||||
continue;
|
||||
if (column2->getPrimaryKey()) {
|
||||
ctx.pushStatus(Error::Gen, "duplicate primary key constraint on %s", a.c_str());
|
||||
return 0;
|
||||
}
|
||||
column2->setPrimaryKey();
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
if (! found) {
|
||||
ctx.pushStatus(Error::Gen, "undefined primary key column %s", a.c_str());
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
// analyze column types
|
||||
for (unsigned i = 1, n = countColumn(); i <= n; i++) {
|
||||
getColumn(i)->analyze(ctx, ctl);
|
||||
if (! ctx.ok())
|
||||
return 0;
|
||||
}
|
||||
// check TupleId
|
||||
unsigned tupleId = 0;
|
||||
for (unsigned i = 1, n = countColumn(); i <= n; i++) {
|
||||
Plan_ddl_column* column = getColumn(i);
|
||||
if (! column->getTupleId())
|
||||
continue;
|
||||
if (i != 1) {
|
||||
ctx.pushStatus(Error::Gen, "tuple id column %u is not first column", i);
|
||||
return 0;
|
||||
}
|
||||
if (tupleId != 0) { // cannot happen now since attr name is fixed
|
||||
ctx.pushStatus(Error::Gen, "duplicate tuple id column %u", i);
|
||||
return 0;
|
||||
}
|
||||
tupleId = i;
|
||||
}
|
||||
if (tupleId != 0) {
|
||||
for (unsigned i = 1, n = countColumn(); i <= n; i++) {
|
||||
Plan_ddl_column* column = getColumn(i);
|
||||
if (i == tupleId)
|
||||
continue;
|
||||
if (! column->getPrimaryKey())
|
||||
continue;
|
||||
ctx.pushStatus(Error::Gen, "cannot have both tuple id and other primary key column %u", i);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
// check auto-increment
|
||||
unsigned autoIncrement = 0;
|
||||
for (unsigned i = 1, n = countColumn(); i <= n; i++) {
|
||||
Plan_ddl_column* column = getColumn(i);
|
||||
if (! column->getAutoIncrement())
|
||||
continue;
|
||||
if (autoIncrement != 0) {
|
||||
ctx.pushStatus(Error::Gen, "duplicate auto-increment column %u", i);
|
||||
return 0;
|
||||
}
|
||||
autoIncrement = i;
|
||||
}
|
||||
if (autoIncrement != 0) {
|
||||
for (unsigned i = 1, n = countColumn(); i <= n; i++) {
|
||||
Plan_ddl_column* column = getColumn(i);
|
||||
if (i == autoIncrement)
|
||||
continue;
|
||||
if (! column->getPrimaryKey())
|
||||
continue;
|
||||
ctx.pushStatus(Error::Gen, "cannot have both auto-increment column and other primary key column %u", i);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
Exec_base*
|
||||
Plan_create_row::codegen(Ctx& ctx, Ctl& ctl)
|
||||
{
|
||||
ctx_assert(false);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
Plan_create_row::print(Ctx& ctx)
|
||||
{
|
||||
ctx.print(" [create_row");
|
||||
for (unsigned i = 1; i <= countColumn(); i++) {
|
||||
Plan_base* a = m_columnList[i];
|
||||
printList(ctx, &a, 1);
|
||||
}
|
||||
for (unsigned i = 1; i <= countConstr(); i++) {
|
||||
Plan_base* a = m_constrList[i];
|
||||
printList(ctx, &a, 1);
|
||||
}
|
||||
}
|
@@ -1,99 +0,0 @@
|
||||
/* Copyright (C) 2003 MySQL AB
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||
|
||||
#ifndef ODBC_CODEGEN_Code_create_row_hpp
|
||||
#define ODBC_CODEGEN_Code_create_row_hpp
|
||||
|
||||
#include <vector>
|
||||
#include <common/common.hpp>
|
||||
#include "Code_base.hpp"
|
||||
#include "Code_ddl_column.hpp"
|
||||
#include "Code_ddl_constr.hpp"
|
||||
|
||||
/**
|
||||
* @class Plan_create_row
|
||||
* @brief Row of columns and constraints in create statement
|
||||
*/
|
||||
class Plan_create_row : public Plan_base {
|
||||
public:
|
||||
Plan_create_row(Plan_root* root);
|
||||
virtual ~Plan_create_row();
|
||||
Plan_base* analyze(Ctx& ctx, Ctl& ctl);
|
||||
Exec_base* codegen(Ctx& ctx, Ctl& ctl);
|
||||
void print(Ctx& ctx);
|
||||
// children
|
||||
unsigned countColumn() const;
|
||||
void addColumn(Plan_ddl_column* column);
|
||||
Plan_ddl_column* getColumn(unsigned i) const;
|
||||
unsigned countConstr() const;
|
||||
void addConstr(Plan_ddl_constr* constr);
|
||||
Plan_ddl_constr* getConstr(unsigned i) const;
|
||||
protected:
|
||||
DdlColumnVector m_columnList;
|
||||
DdlConstrVector m_constrList;
|
||||
};
|
||||
|
||||
inline
|
||||
Plan_create_row::Plan_create_row(Plan_root* root) :
|
||||
Plan_base(root),
|
||||
m_columnList(1),
|
||||
m_constrList(1)
|
||||
{
|
||||
}
|
||||
|
||||
// children
|
||||
|
||||
inline unsigned
|
||||
Plan_create_row::countColumn() const
|
||||
{
|
||||
return m_columnList.size() - 1;
|
||||
}
|
||||
|
||||
inline void
|
||||
Plan_create_row::addColumn(Plan_ddl_column* column)
|
||||
{
|
||||
ctx_assert(column != 0);
|
||||
m_columnList.push_back(column);
|
||||
}
|
||||
|
||||
inline Plan_ddl_column*
|
||||
Plan_create_row::getColumn(unsigned i) const
|
||||
{
|
||||
ctx_assert(1 <= i && i <= m_columnList.size() && m_columnList[i] != 0);
|
||||
return m_columnList[i];
|
||||
}
|
||||
|
||||
inline unsigned
|
||||
Plan_create_row::countConstr() const
|
||||
{
|
||||
return m_constrList.size() - 1;
|
||||
}
|
||||
|
||||
inline void
|
||||
Plan_create_row::addConstr(Plan_ddl_constr* constr)
|
||||
{
|
||||
ctx_assert(constr != 0);
|
||||
m_constrList.push_back(constr);
|
||||
}
|
||||
|
||||
inline Plan_ddl_constr*
|
||||
Plan_create_row::getConstr(unsigned i) const
|
||||
{
|
||||
ctx_assert(1 <= i && i <= m_constrList.size() && m_constrList[i] != 0);
|
||||
return m_constrList[i];
|
||||
}
|
||||
|
||||
#endif
|
@@ -1,137 +0,0 @@
|
||||
/* Copyright (C) 2003 MySQL AB
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||
|
||||
#include <common/StmtArea.hpp>
|
||||
#include "Code_create_table.hpp"
|
||||
#include "Code_root.hpp"
|
||||
|
||||
// Plan_create_table
|
||||
|
||||
Plan_create_table::~Plan_create_table()
|
||||
{
|
||||
}
|
||||
|
||||
Plan_base*
|
||||
Plan_create_table::analyze(Ctx& ctx, Ctl& ctl)
|
||||
{
|
||||
stmtArea().stmtInfo().setName(Stmt_name_create_table);
|
||||
// analyze the create row
|
||||
ctx_assert(m_createRow != 0);
|
||||
m_createRow->analyze(ctx, ctl);
|
||||
if (! ctx.ok())
|
||||
return 0;
|
||||
return this;
|
||||
}
|
||||
|
||||
void
|
||||
Plan_create_table::describe(Ctx& ctx)
|
||||
{
|
||||
stmtArea().setFunction(ctx, "CREATE TABLE", SQL_DIAG_CREATE_TABLE);
|
||||
}
|
||||
|
||||
Exec_base*
|
||||
Plan_create_table::codegen(Ctx& ctx, Ctl& ctl)
|
||||
{
|
||||
ctx_assert(m_createRow != 0);
|
||||
Exec_create_table* exec = new Exec_create_table(ctl.m_execRoot);
|
||||
ctl.m_execRoot->saveNode(exec);
|
||||
const unsigned count = m_createRow->countColumn();
|
||||
Exec_create_table::Code::Attr* attrList = new Exec_create_table::Code::Attr[1 + count];
|
||||
unsigned tupleId = 0;
|
||||
unsigned autoIncrement = 0;
|
||||
for (unsigned i = 1; i <= count; i++) {
|
||||
Plan_ddl_column* column = m_createRow->getColumn(i);
|
||||
Exec_create_table::Code::Attr& attr = attrList[i];
|
||||
attr.m_attrName.assign(column->getName());
|
||||
attr.m_sqlType = column->sqlType();
|
||||
attr.m_tupleKey = column->getPrimaryKey();
|
||||
attr.m_tupleId = column->getTupleId();
|
||||
attr.m_autoIncrement = column->getAutoIncrement();
|
||||
if (attr.m_tupleId)
|
||||
tupleId = i;
|
||||
if (attr.m_autoIncrement)
|
||||
autoIncrement = i;
|
||||
attr.m_defaultValue = 0;
|
||||
Plan_expr* expr;
|
||||
if ((expr = column->getDefaultValue()) != 0) {
|
||||
Exec_expr* execExpr = static_cast<Exec_expr*>(expr->codegen(ctx, ctl));
|
||||
if (! ctx.ok())
|
||||
return 0;
|
||||
ctx_assert(execExpr != 0);
|
||||
attr.m_defaultValue = execExpr;
|
||||
}
|
||||
}
|
||||
Exec_create_table::Code& code = *new Exec_create_table::Code(m_name, count, attrList, tupleId, autoIncrement);
|
||||
exec->setCode(code);
|
||||
code.m_fragmentType = m_fragmentType;
|
||||
code.m_logging = m_logging;
|
||||
return exec;
|
||||
}
|
||||
|
||||
void
|
||||
Plan_create_table::print(Ctx& ctx)
|
||||
{
|
||||
ctx.print(" [create_table '%s'", m_name.c_str());
|
||||
Plan_base* a[] = { m_createRow };
|
||||
printList(ctx, a, 1);
|
||||
ctx.print("]");
|
||||
}
|
||||
|
||||
// Exec_create_table
|
||||
|
||||
Exec_create_table::Code::~Code()
|
||||
{
|
||||
delete[] m_attrList;
|
||||
}
|
||||
|
||||
Exec_create_table::Data::~Data()
|
||||
{
|
||||
}
|
||||
|
||||
Exec_create_table::~Exec_create_table()
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
Exec_create_table::alloc(Ctx& ctx, Ctl& ctl)
|
||||
{
|
||||
const Code& code = getCode();
|
||||
for (unsigned i = 1; i <= code.m_attrCount; i++) {
|
||||
const Code::Attr& attr = code.m_attrList[i];
|
||||
if (attr.m_defaultValue != 0)
|
||||
attr.m_defaultValue->alloc(ctx, ctl);
|
||||
}
|
||||
Data& data = *new Data;
|
||||
setData(data);
|
||||
}
|
||||
|
||||
void
|
||||
Exec_create_table::close(Ctx& ctx)
|
||||
{
|
||||
const Code& code = getCode();
|
||||
for (unsigned i = 1; i <= code.m_attrCount; i++) {
|
||||
const Code::Attr& attr = code.m_attrList[i];
|
||||
if (attr.m_defaultValue != 0)
|
||||
attr.m_defaultValue->close(ctx);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Exec_create_table::print(Ctx& ctx)
|
||||
{
|
||||
const Code& code = getCode();
|
||||
ctx.print(" [create_table %s]", code.m_tableName.c_str());
|
||||
}
|
@@ -1,178 +0,0 @@
|
||||
/* Copyright (C) 2003 MySQL AB
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||
|
||||
#ifndef ODBC_CODEGEN_Code_create_table_hpp
|
||||
#define ODBC_CODEGEN_Code_create_table_hpp
|
||||
|
||||
#include <vector>
|
||||
#include <common/common.hpp>
|
||||
#include "Code_ddl.hpp"
|
||||
#include "Code_ddl_row.hpp"
|
||||
#include "Code_create_row.hpp"
|
||||
|
||||
class DictTable;
|
||||
class DictColumn;
|
||||
|
||||
/**
|
||||
* @class Plan_create_table
|
||||
* @brief Create table in PlanTree
|
||||
*/
|
||||
class Plan_create_table : public Plan_ddl {
|
||||
public:
|
||||
Plan_create_table(Plan_root* root, const BaseString& name);
|
||||
virtual ~Plan_create_table();
|
||||
Plan_base* analyze(Ctx& ctx, Ctl& ctl);
|
||||
Exec_base* codegen(Ctx& ctx, Ctl& ctl);
|
||||
void describe(Ctx & ctx);
|
||||
void print(Ctx& ctx);
|
||||
// attributes
|
||||
const BaseString& getName() const;
|
||||
// children
|
||||
void setCreateRow(Plan_create_row* createRow);
|
||||
void setFragmentType(NdbDictionary::Object::FragmentType fragmentType);
|
||||
void setLogging(bool logging);
|
||||
protected:
|
||||
BaseString m_name;
|
||||
Plan_create_row* m_createRow;
|
||||
NdbDictionary::Object::FragmentType m_fragmentType;
|
||||
bool m_logging;
|
||||
};
|
||||
|
||||
inline
|
||||
Plan_create_table::Plan_create_table(Plan_root* root, const BaseString& name) :
|
||||
Plan_ddl(root),
|
||||
m_name(name),
|
||||
m_createRow(0),
|
||||
m_fragmentType(NdbDictionary::Object::FragUndefined),
|
||||
m_logging(true)
|
||||
{
|
||||
}
|
||||
|
||||
inline const BaseString&
|
||||
Plan_create_table::getName() const
|
||||
{
|
||||
return m_name;
|
||||
}
|
||||
|
||||
// children
|
||||
|
||||
inline void
|
||||
Plan_create_table::setCreateRow(Plan_create_row* createRow)
|
||||
{
|
||||
ctx_assert(createRow != 0);
|
||||
m_createRow = createRow;
|
||||
}
|
||||
|
||||
inline void
|
||||
Plan_create_table::setFragmentType(NdbDictionary::Object::FragmentType fragmentType)
|
||||
{
|
||||
m_fragmentType = fragmentType;
|
||||
}
|
||||
|
||||
inline void
|
||||
Plan_create_table::setLogging(bool logging)
|
||||
{
|
||||
m_logging = logging;
|
||||
}
|
||||
|
||||
/**
|
||||
* @class Exec_create_table
|
||||
* @brief Create table in ExecTree
|
||||
*/
|
||||
class Exec_create_table : public Exec_ddl {
|
||||
public:
|
||||
class Code : public Exec_ddl::Code {
|
||||
public:
|
||||
struct Attr {
|
||||
Attr() : m_defaultValue(0) {}
|
||||
BaseString m_attrName;
|
||||
SqlType m_sqlType;
|
||||
bool m_tupleKey;
|
||||
bool m_tupleId;
|
||||
bool m_autoIncrement;
|
||||
Exec_expr* m_defaultValue;
|
||||
};
|
||||
Code(const BaseString& tableName, unsigned attrCount, const Attr* attrList, unsigned tupleId, unsigned autoIncrement);
|
||||
virtual ~Code();
|
||||
protected:
|
||||
friend class Plan_create_table;
|
||||
friend class Exec_create_table;
|
||||
const BaseString m_tableName;
|
||||
const unsigned m_attrCount;
|
||||
const Attr* const m_attrList;
|
||||
unsigned m_tupleId;
|
||||
unsigned m_autoIncrement;
|
||||
NdbDictionary::Object::FragmentType m_fragmentType;
|
||||
bool m_logging;
|
||||
};
|
||||
class Data : public Exec_ddl::Data {
|
||||
public:
|
||||
Data();
|
||||
virtual ~Data();
|
||||
protected:
|
||||
friend class Exec_create_table;
|
||||
};
|
||||
Exec_create_table(Exec_root* root);
|
||||
virtual ~Exec_create_table();
|
||||
void alloc(Ctx& ctx, Ctl& ctl);
|
||||
void execute(Ctx& ctx, Ctl& ctl);
|
||||
void close(Ctx& ctx);
|
||||
void print(Ctx& ctx);
|
||||
// children
|
||||
const Code& getCode() const;
|
||||
Data& getData() const;
|
||||
};
|
||||
|
||||
inline
|
||||
Exec_create_table::Code::Code(const BaseString& tableName, unsigned attrCount, const Attr* attrList, unsigned tupleId, unsigned autoIncrement) :
|
||||
m_tableName(tableName),
|
||||
m_attrCount(attrCount),
|
||||
m_attrList(attrList),
|
||||
m_tupleId(tupleId),
|
||||
m_autoIncrement(autoIncrement),
|
||||
m_fragmentType(NdbDictionary::Object::FragUndefined),
|
||||
m_logging(true)
|
||||
{
|
||||
}
|
||||
|
||||
inline
|
||||
Exec_create_table::Data::Data()
|
||||
{
|
||||
}
|
||||
|
||||
inline
|
||||
Exec_create_table::Exec_create_table(Exec_root* root) :
|
||||
Exec_ddl(root)
|
||||
{
|
||||
}
|
||||
|
||||
// children
|
||||
|
||||
inline const Exec_create_table::Code&
|
||||
Exec_create_table::getCode() const
|
||||
{
|
||||
const Code* code = static_cast<const Code*>(m_code);
|
||||
return *code;
|
||||
}
|
||||
|
||||
inline Exec_create_table::Data&
|
||||
Exec_create_table::getData() const
|
||||
{
|
||||
Data* data = static_cast<Data*>(m_data);
|
||||
return *data;
|
||||
}
|
||||
|
||||
#endif
|
@@ -1,44 +0,0 @@
|
||||
/* Copyright (C) 2003 MySQL AB
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||
|
||||
#include <NdbApi.hpp>
|
||||
#include <common/StmtArea.hpp>
|
||||
#include "Code_data_type.hpp"
|
||||
|
||||
// Plan_data_type
|
||||
|
||||
Plan_data_type::~Plan_data_type()
|
||||
{
|
||||
}
|
||||
|
||||
Plan_base*
|
||||
Plan_data_type::analyze(Ctx& ctx, Ctl& ctl)
|
||||
{
|
||||
return this;
|
||||
}
|
||||
|
||||
Exec_base*
|
||||
Plan_data_type::codegen(Ctx& ctx, Ctl& ctl)
|
||||
{
|
||||
ctx_assert(false);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
Plan_data_type::print(Ctx& ctx)
|
||||
{
|
||||
ctx.print(" [data_type]");
|
||||
}
|
@@ -1,49 +0,0 @@
|
||||
/* Copyright (C) 2003 MySQL AB
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||
|
||||
#ifndef ODBC_CODEGEN_Code_data_type_hpp
|
||||
#define ODBC_CODEGEN_Code_data_type_hpp
|
||||
|
||||
#include <common/common.hpp>
|
||||
#include <common/DataType.hpp>
|
||||
#include "Code_base.hpp"
|
||||
|
||||
/**
|
||||
* @class Plan_data_type
|
||||
* @brief Data type in DDL statement
|
||||
*
|
||||
* This is pure plan node.
|
||||
*/
|
||||
class Plan_data_type : public Plan_base {
|
||||
public:
|
||||
Plan_data_type(Plan_root* root, const SqlType& sqlType);
|
||||
virtual ~Plan_data_type();
|
||||
Plan_base* analyze(Ctx& ctx, Ctl& ctl);
|
||||
Exec_base* codegen(Ctx& ctx, Ctl& ctl);
|
||||
void print(Ctx& ctx);
|
||||
private:
|
||||
friend class Plan_ddl_column;
|
||||
SqlType m_sqlType;
|
||||
};
|
||||
|
||||
inline
|
||||
Plan_data_type::Plan_data_type(Plan_root* root, const SqlType& sqlType) :
|
||||
Plan_base(root),
|
||||
m_sqlType(sqlType)
|
||||
{
|
||||
}
|
||||
|
||||
#endif
|
@@ -1,37 +0,0 @@
|
||||
/* Copyright (C) 2003 MySQL AB
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||
|
||||
#include "Code_ddl.hpp"
|
||||
|
||||
// Plan_ddl
|
||||
|
||||
Plan_ddl::~Plan_ddl()
|
||||
{
|
||||
}
|
||||
|
||||
// Exec_ddl
|
||||
|
||||
Exec_ddl::Code::~Code()
|
||||
{
|
||||
}
|
||||
|
||||
Exec_ddl::Data::~Data()
|
||||
{
|
||||
}
|
||||
|
||||
Exec_ddl::~Exec_ddl()
|
||||
{
|
||||
}
|
@@ -1,63 +0,0 @@
|
||||
/* Copyright (C) 2003 MySQL AB
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||
|
||||
#ifndef ODBC_CODEGEN_Code_ddl_hpp
|
||||
#define ODBC_CODEGEN_Code_ddl_hpp
|
||||
|
||||
#include <common/common.hpp>
|
||||
#include "Code_stmt.hpp"
|
||||
|
||||
/**
|
||||
* @class Plan_ddl
|
||||
* @brief Base class for DDL statements in PlanTree
|
||||
*/
|
||||
class Plan_ddl : public Plan_stmt {
|
||||
public:
|
||||
Plan_ddl(Plan_root* root);
|
||||
virtual ~Plan_ddl() = 0;
|
||||
};
|
||||
|
||||
inline
|
||||
Plan_ddl::Plan_ddl(Plan_root* root) :
|
||||
Plan_stmt(root)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @class Exec_ddl
|
||||
* @brief Base class for DDL statements in ExecTree
|
||||
*/
|
||||
class Exec_ddl : public Exec_stmt {
|
||||
public:
|
||||
class Code : public Exec_stmt::Code {
|
||||
public:
|
||||
virtual ~Code() = 0;
|
||||
};
|
||||
class Data : public Exec_stmt::Data {
|
||||
public:
|
||||
virtual ~Data() = 0;
|
||||
};
|
||||
Exec_ddl(Exec_root* root);
|
||||
virtual ~Exec_ddl() = 0;
|
||||
};
|
||||
|
||||
inline
|
||||
Exec_ddl::Exec_ddl(Exec_root* root) :
|
||||
Exec_stmt(root)
|
||||
{
|
||||
}
|
||||
|
||||
#endif
|
@@ -1,104 +0,0 @@
|
||||
/* Copyright (C) 2003 MySQL AB
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||
|
||||
#include <NdbApi.hpp>
|
||||
#include <common/StmtArea.hpp>
|
||||
#include "Code_ddl_column.hpp"
|
||||
#include "Code_expr_conv.hpp"
|
||||
#include "Code_root.hpp"
|
||||
|
||||
// Plan_ddl_column
|
||||
|
||||
Plan_ddl_column::~Plan_ddl_column()
|
||||
{
|
||||
}
|
||||
|
||||
Plan_base*
|
||||
Plan_ddl_column::analyze(Ctx& ctx, Ctl& ctl)
|
||||
{
|
||||
ctx_assert(m_type != 0);
|
||||
if (! m_type->m_sqlType.nullable()) {
|
||||
m_nullable = false;
|
||||
}
|
||||
m_sqlType = m_type->m_sqlType;
|
||||
m_sqlType.nullable(m_nullable);
|
||||
const BaseString& name = getName();
|
||||
if (m_unSigned) {
|
||||
switch (m_sqlType.type()) {
|
||||
case SqlType::Smallint:
|
||||
case SqlType::Integer:
|
||||
case SqlType::Bigint:
|
||||
break;
|
||||
default:
|
||||
ctx.pushStatus(Error::Gen, "invalid unsigned qualifier on column %s", name.c_str());
|
||||
return 0;
|
||||
}
|
||||
m_sqlType.unSigned(true);
|
||||
}
|
||||
if (strcmp(name.c_str(), "NDB$TID") == 0) {
|
||||
if (! m_primaryKey) {
|
||||
ctx.pushStatus(Error::Gen, "column %s must be a primary key", name.c_str());
|
||||
return 0;
|
||||
}
|
||||
if (sqlType().type() != SqlType::Bigint || ! sqlType().unSigned()) {
|
||||
ctx.pushStatus(Error::Gen, "tuple id %s must have type BIGINT UNSIGNED", name.c_str());
|
||||
return 0;
|
||||
}
|
||||
setTupleId();
|
||||
}
|
||||
if (m_autoIncrement) {
|
||||
if (! m_primaryKey) {
|
||||
ctx.pushStatus(Error::Gen, "auto-increment column %s must be a primary key", name.c_str());
|
||||
return 0;
|
||||
}
|
||||
if (sqlType().type() != SqlType::Smallint && sqlType().type() != SqlType::Integer && sqlType().type() != SqlType::Bigint) {
|
||||
ctx.pushStatus(Error::Gen, "auto-increment column %s must have an integral type", name.c_str());
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
if (m_defaultValue != 0) {
|
||||
if (m_primaryKey) {
|
||||
ctx.pushStatus(Sqlstate::_42000, Error::Gen, "default value not allowed on primary key column %s", name.c_str());
|
||||
return 0;
|
||||
}
|
||||
m_defaultValue->analyze(ctx, ctl);
|
||||
if (! ctx.ok())
|
||||
return 0;
|
||||
// insert conversion node
|
||||
Plan_expr_conv* exprConv = new Plan_expr_conv(m_root, sqlType());
|
||||
m_root->saveNode(exprConv);
|
||||
exprConv->setExpr(m_defaultValue);
|
||||
Plan_expr* expr = static_cast<Plan_expr*>(exprConv->analyze(ctx, ctl));
|
||||
if (! ctx.ok())
|
||||
return 0;
|
||||
ctx_assert(expr != 0);
|
||||
m_defaultValue = expr;
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
Exec_base*
|
||||
Plan_ddl_column::codegen(Ctx& ctx, Ctl& ctl)
|
||||
{
|
||||
ctx_assert(false);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
Plan_ddl_column::print(Ctx& ctx)
|
||||
{
|
||||
ctx.print(" [ddl_column %s key=%d id=%d]", getPrintName(), m_primaryKey, m_tupleId);
|
||||
}
|
@@ -1,150 +0,0 @@
|
||||
/* Copyright (C) 2003 MySQL AB
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||
|
||||
#ifndef ODBC_CODEGEN_Code_ddl_column_hpp
|
||||
#define ODBC_CODEGEN_Code_ddl_column_hpp
|
||||
|
||||
#include <common/common.hpp>
|
||||
#include "Code_column.hpp"
|
||||
#include "Code_data_type.hpp"
|
||||
#include "Code_expr.hpp"
|
||||
|
||||
class DictColumn;
|
||||
class Plan_table;
|
||||
|
||||
/**
|
||||
* @class Plan_ddl_column
|
||||
* @brief Column in DDL statement
|
||||
*/
|
||||
class Plan_ddl_column : public Plan_base, public Plan_column {
|
||||
public:
|
||||
Plan_ddl_column(Plan_root* root, const BaseString& name);
|
||||
virtual ~Plan_ddl_column();
|
||||
Plan_base* analyze(Ctx& ctx, Ctl& ctl);
|
||||
Exec_base* codegen(Ctx& ctx, Ctl& ctl);
|
||||
void print(Ctx& ctx);
|
||||
// attributes
|
||||
void setNotNull();
|
||||
void setUnSigned();
|
||||
void setPrimaryKey();
|
||||
bool getPrimaryKey() const;
|
||||
void setTupleId();
|
||||
bool getTupleId() const;
|
||||
void setAutoIncrement();
|
||||
bool getAutoIncrement() const;
|
||||
// children
|
||||
void setType(Plan_data_type* type);
|
||||
void setDefaultValue(Plan_expr* defaultValue);
|
||||
Plan_expr* getDefaultValue() const;
|
||||
protected:
|
||||
friend class Plan_create_row;
|
||||
Plan_data_type* m_type;
|
||||
Plan_expr* m_defaultValue;
|
||||
bool m_nullable;
|
||||
bool m_unSigned;
|
||||
bool m_primaryKey;
|
||||
bool m_tupleId;
|
||||
bool m_autoIncrement;
|
||||
};
|
||||
|
||||
inline
|
||||
Plan_ddl_column::Plan_ddl_column(Plan_root* root, const BaseString& name) :
|
||||
Plan_base(root),
|
||||
Plan_column(Type_ddl, name),
|
||||
m_type(0),
|
||||
m_defaultValue(0),
|
||||
m_nullable(true),
|
||||
m_unSigned(false),
|
||||
m_primaryKey(false),
|
||||
m_tupleId(false),
|
||||
m_autoIncrement(false)
|
||||
{
|
||||
}
|
||||
|
||||
inline void
|
||||
Plan_ddl_column::setNotNull()
|
||||
{
|
||||
m_nullable = false;
|
||||
}
|
||||
|
||||
inline void
|
||||
Plan_ddl_column::setUnSigned()
|
||||
{
|
||||
m_unSigned = true;
|
||||
}
|
||||
|
||||
inline void
|
||||
Plan_ddl_column::setPrimaryKey()
|
||||
{
|
||||
m_nullable = false;
|
||||
m_primaryKey = true;
|
||||
}
|
||||
|
||||
inline bool
|
||||
Plan_ddl_column::getPrimaryKey() const
|
||||
{
|
||||
return m_primaryKey;
|
||||
}
|
||||
|
||||
inline void
|
||||
Plan_ddl_column::setTupleId()
|
||||
{
|
||||
m_nullable = false;
|
||||
m_tupleId = true;
|
||||
}
|
||||
|
||||
inline bool
|
||||
Plan_ddl_column::getTupleId() const
|
||||
{
|
||||
return m_tupleId;
|
||||
}
|
||||
|
||||
inline void
|
||||
Plan_ddl_column::setAutoIncrement()
|
||||
{
|
||||
m_nullable = false;
|
||||
m_autoIncrement = true;
|
||||
}
|
||||
|
||||
inline bool
|
||||
Plan_ddl_column::getAutoIncrement() const
|
||||
{
|
||||
return m_autoIncrement;
|
||||
}
|
||||
|
||||
// children
|
||||
|
||||
inline void
|
||||
Plan_ddl_column::setType(Plan_data_type* type)
|
||||
{
|
||||
ctx_assert(type != 0);
|
||||
m_type = type;
|
||||
}
|
||||
|
||||
inline void
|
||||
Plan_ddl_column::setDefaultValue(Plan_expr* defaultValue)
|
||||
{
|
||||
ctx_assert(defaultValue != 0);
|
||||
m_defaultValue = defaultValue;
|
||||
}
|
||||
|
||||
inline Plan_expr*
|
||||
Plan_ddl_column::getDefaultValue() const
|
||||
{
|
||||
return m_defaultValue;
|
||||
}
|
||||
|
||||
#endif
|
@@ -1,51 +0,0 @@
|
||||
/* Copyright (C) 2003 MySQL AB
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||
|
||||
#include <NdbApi.hpp>
|
||||
#include <common/StmtArea.hpp>
|
||||
#include "Code_ddl_constr.hpp"
|
||||
|
||||
// Plan_ddl_constr
|
||||
|
||||
Plan_ddl_constr::~Plan_ddl_constr()
|
||||
{
|
||||
}
|
||||
|
||||
Plan_base*
|
||||
Plan_ddl_constr::analyze(Ctx& ctx, Ctl& ctl)
|
||||
{
|
||||
ctx_assert(m_ddlRow != 0);
|
||||
m_ddlRow->analyze(ctx, ctl);
|
||||
if (! ctx.ok())
|
||||
return 0;
|
||||
return this;
|
||||
}
|
||||
|
||||
Exec_base*
|
||||
Plan_ddl_constr::codegen(Ctx& ctx, Ctl& ctl)
|
||||
{
|
||||
ctx_assert(false);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
Plan_ddl_constr::print(Ctx& ctx)
|
||||
{
|
||||
ctx.print(" [ddl_constr");
|
||||
Plan_base* a[] = { m_ddlRow };
|
||||
printList(ctx, a, 1);
|
||||
ctx.print("]");
|
||||
}
|
@@ -1,65 +0,0 @@
|
||||
/* Copyright (C) 2003 MySQL AB
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||
|
||||
#ifndef ODBC_CODEGEN_Code_ddl_constr_hpp
|
||||
#define ODBC_CODEGEN_Code_ddl_constr_hpp
|
||||
|
||||
#include <common/common.hpp>
|
||||
#include "Code_ddl_row.hpp"
|
||||
|
||||
/**
|
||||
* @class Plan_ddl_constr
|
||||
* @brief Constraint in DDL statement
|
||||
*
|
||||
* Only unnamed primary key constraint exists.
|
||||
*/
|
||||
class Plan_ddl_constr : public Plan_base {
|
||||
public:
|
||||
Plan_ddl_constr(Plan_root* root);
|
||||
virtual ~Plan_ddl_constr();
|
||||
Plan_base* analyze(Ctx& ctx, Ctl& ctl);
|
||||
Exec_base* codegen(Ctx& ctx, Ctl& ctl);
|
||||
void print(Ctx& ctx);
|
||||
// children
|
||||
void setRow(Plan_ddl_row* ddlRow);
|
||||
Plan_ddl_row* getRow() const;
|
||||
protected:
|
||||
Plan_ddl_row* m_ddlRow;
|
||||
};
|
||||
|
||||
inline
|
||||
Plan_ddl_constr::Plan_ddl_constr(Plan_root* root) :
|
||||
Plan_base(root)
|
||||
{
|
||||
}
|
||||
|
||||
// children
|
||||
|
||||
inline void
|
||||
Plan_ddl_constr::setRow(Plan_ddl_row* ddlRow)
|
||||
{
|
||||
ctx_assert(ddlRow != 0);
|
||||
m_ddlRow = ddlRow;
|
||||
}
|
||||
|
||||
inline Plan_ddl_row*
|
||||
Plan_ddl_constr::getRow() const
|
||||
{
|
||||
ctx_assert(m_ddlRow != 0);
|
||||
return m_ddlRow;
|
||||
}
|
||||
|
||||
#endif
|
@@ -1,54 +0,0 @@
|
||||
/* Copyright (C) 2003 MySQL AB
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||
|
||||
#include "Code_ddl_row.hpp"
|
||||
#include "Code_ddl_column.hpp"
|
||||
#include "Code_ddl_constr.hpp"
|
||||
|
||||
Plan_ddl_row::~Plan_ddl_row()
|
||||
{
|
||||
}
|
||||
|
||||
Plan_base*
|
||||
Plan_ddl_row::analyze(Ctx& ctx, Ctl& ctl)
|
||||
{
|
||||
// analyze the columns
|
||||
for (unsigned i = 1, n = countColumn(); i <= n; i++) {
|
||||
Plan_ddl_column* column = getColumn(i);
|
||||
column->analyze(ctx, ctl);
|
||||
if (! ctx.ok())
|
||||
return 0;
|
||||
}
|
||||
// node was not replaced
|
||||
return this;
|
||||
}
|
||||
|
||||
Exec_base*
|
||||
Plan_ddl_row::codegen(Ctx& ctx, Ctl& ctl)
|
||||
{
|
||||
ctx_assert(false);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
Plan_ddl_row::print(Ctx& ctx)
|
||||
{
|
||||
ctx.print(" [ddl_row");
|
||||
for (unsigned i = 1, n = countColumn(); i <= n; i++) {
|
||||
Plan_base* a = m_columnList[i];
|
||||
printList(ctx, &a, 1);
|
||||
}
|
||||
}
|
@@ -1,72 +0,0 @@
|
||||
/* Copyright (C) 2003 MySQL AB
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||
|
||||
#ifndef ODBC_CODEGEN_Code_ddl_row_hpp
|
||||
#define ODBC_CODEGEN_Code_ddl_row_hpp
|
||||
|
||||
#include <common/common.hpp>
|
||||
#include "Code_base.hpp"
|
||||
#include "Code_ddl_column.hpp"
|
||||
|
||||
/**
|
||||
* @class Plan_ddl_row
|
||||
* @brief Row of columns in create statement
|
||||
*/
|
||||
class Plan_ddl_row : public Plan_base {
|
||||
public:
|
||||
Plan_ddl_row(Plan_root* root);
|
||||
virtual ~Plan_ddl_row();
|
||||
Plan_base* analyze(Ctx& ctx, Ctl& ctl);
|
||||
Exec_base* codegen(Ctx& ctx, Ctl& ctl);
|
||||
void print(Ctx& ctx);
|
||||
// children
|
||||
unsigned countColumn() const;
|
||||
void addColumn(Plan_ddl_column* column);
|
||||
Plan_ddl_column* getColumn(unsigned i) const;
|
||||
protected:
|
||||
DdlColumnVector m_columnList;
|
||||
};
|
||||
|
||||
inline
|
||||
Plan_ddl_row::Plan_ddl_row(Plan_root* root) :
|
||||
Plan_base(root),
|
||||
m_columnList(1)
|
||||
{
|
||||
}
|
||||
|
||||
// children
|
||||
|
||||
inline unsigned
|
||||
Plan_ddl_row::countColumn() const
|
||||
{
|
||||
return m_columnList.size() - 1;
|
||||
}
|
||||
|
||||
inline void
|
||||
Plan_ddl_row::addColumn(Plan_ddl_column* column)
|
||||
{
|
||||
ctx_assert(column != 0);
|
||||
m_columnList.push_back(column);
|
||||
}
|
||||
|
||||
inline Plan_ddl_column*
|
||||
Plan_ddl_row::getColumn(unsigned i) const
|
||||
{
|
||||
ctx_assert(1 <= i && i <= countColumn() && m_columnList[i] != 0);
|
||||
return m_columnList[i];
|
||||
}
|
||||
|
||||
#endif
|
@@ -1,205 +0,0 @@
|
||||
/* Copyright (C) 2003 MySQL AB
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||
|
||||
#include <common/StmtArea.hpp>
|
||||
#include "Code_delete.hpp"
|
||||
#include "Code_delete_lookup.hpp"
|
||||
#include "Code_delete_index.hpp"
|
||||
#include "Code_delete_scan.hpp"
|
||||
#include "Code_query_filter.hpp"
|
||||
#include "Code_query_lookup.hpp"
|
||||
#include "Code_query_index.hpp"
|
||||
#include "Code_query_scan.hpp"
|
||||
#include "Code_query_range.hpp"
|
||||
#include "Code_query_repeat.hpp"
|
||||
#include "Code_table.hpp"
|
||||
#include "Code_root.hpp"
|
||||
|
||||
Plan_delete::~Plan_delete()
|
||||
{
|
||||
}
|
||||
|
||||
Plan_base*
|
||||
Plan_delete::analyze(Ctx& ctx, Ctl& ctl)
|
||||
{
|
||||
stmtArea().stmtInfo().setName(Stmt_name_delete);
|
||||
// analyze the table
|
||||
ctx_assert(m_table != 0);
|
||||
m_table->analyze(ctx, ctl);
|
||||
if (! ctx.ok())
|
||||
return 0;
|
||||
// set name resolution scope
|
||||
ctl.m_tableList.resize(1 + 1); // indexed from 1
|
||||
ctl.m_tableList[1] = m_table;
|
||||
Plan_dml* stmt = 0;
|
||||
if (m_pred != 0) {
|
||||
// analyze the predicate
|
||||
ctl.m_topand = true;
|
||||
ctl.m_extra = false;
|
||||
m_pred = static_cast<Plan_pred*>(m_pred->analyze(ctx, ctl));
|
||||
if (! ctx.ok())
|
||||
return 0;
|
||||
ctx_assert(m_pred != 0);
|
||||
// check for key match
|
||||
Plan_table::Index* indexBest = 0;
|
||||
for (unsigned i = 0; i <= m_table->indexCount(); i++) {
|
||||
Plan_table::Index& index = m_table->m_indexList[i];
|
||||
TableSet tsDone;
|
||||
m_table->resolveSet(ctx, index, tsDone);
|
||||
if (! ctx.ok())
|
||||
return 0;
|
||||
if (! index.m_keyFound)
|
||||
continue;
|
||||
// prefer smaller rank, less unused keys
|
||||
int k;
|
||||
(k = (indexBest == 0)) ||
|
||||
(k = (indexBest->m_rank - index.m_rank)) ||
|
||||
(k = (indexBest->m_keyCountUnused - index.m_keyCountUnused));
|
||||
if (k > 0)
|
||||
indexBest = &index;
|
||||
}
|
||||
if (indexBest != 0) {
|
||||
const bool exactKey = indexBest->m_rank <= 1 ? m_table->exactKey(ctx, indexBest) : false;
|
||||
const bool direct = ! ctl.m_extra && exactKey;
|
||||
ctx_log3(("delete direct=%d: extra=%d exact=%d", direct, ctl.m_extra, exactKey));
|
||||
if (indexBest->m_rank == 0) {
|
||||
// primary key
|
||||
Plan_delete_lookup* deleteLookup = new Plan_delete_lookup(m_root);
|
||||
m_root->saveNode(deleteLookup);
|
||||
deleteLookup->setTable(m_table);
|
||||
if (direct) {
|
||||
// key match with no extra conditions
|
||||
Plan_query_repeat* queryRepeat = new Plan_query_repeat(m_root, 1);
|
||||
m_root->saveNode(queryRepeat);
|
||||
deleteLookup->setQuery(queryRepeat);
|
||||
} else {
|
||||
// key match with extra conditions
|
||||
Plan_query_lookup* queryLookup = new Plan_query_lookup(m_root);
|
||||
m_root->saveNode(queryLookup);
|
||||
Plan_query_filter* queryFilter = new Plan_query_filter(m_root);
|
||||
m_root->saveNode(queryFilter);
|
||||
queryLookup->setTable(m_table);
|
||||
queryFilter->setQuery(queryLookup);
|
||||
queryFilter->setPred(m_pred);
|
||||
queryFilter->m_topTable = m_table;
|
||||
deleteLookup->setQuery(queryFilter);
|
||||
}
|
||||
stmt = deleteLookup;
|
||||
} else if (indexBest->m_rank == 1) {
|
||||
// hash index
|
||||
Plan_delete_index* deleteIndex = new Plan_delete_index(m_root);
|
||||
m_root->saveNode(deleteIndex);
|
||||
deleteIndex->setTable(m_table, indexBest);
|
||||
if (direct) {
|
||||
// key match with no extra conditions
|
||||
Plan_query_repeat* queryRepeat = new Plan_query_repeat(m_root, 1);
|
||||
m_root->saveNode(queryRepeat);
|
||||
deleteIndex->setQuery(queryRepeat);
|
||||
} else {
|
||||
// key match with extra conditions
|
||||
Plan_query_index* queryIndex = new Plan_query_index(m_root);
|
||||
m_root->saveNode(queryIndex);
|
||||
Plan_query_filter* queryFilter = new Plan_query_filter(m_root);
|
||||
m_root->saveNode(queryFilter);
|
||||
queryIndex->setTable(m_table, indexBest);
|
||||
queryFilter->setQuery(queryIndex);
|
||||
queryFilter->setPred(m_pred);
|
||||
queryFilter->m_topTable = m_table;
|
||||
deleteIndex->setQuery(queryFilter);
|
||||
}
|
||||
stmt = deleteIndex;
|
||||
} else if (indexBest->m_rank == 2) {
|
||||
// ordered index
|
||||
Plan_delete_scan* deleteScan = new Plan_delete_scan(m_root);
|
||||
m_root->saveNode(deleteScan);
|
||||
Plan_query_filter* queryFilter = new Plan_query_filter(m_root);
|
||||
m_root->saveNode(queryFilter);
|
||||
Plan_query_range* queryRange = new Plan_query_range(m_root);
|
||||
m_root->saveNode(queryRange);
|
||||
queryRange->setTable(m_table, indexBest);
|
||||
queryRange->setExclusive();
|
||||
queryFilter->setQuery(queryRange);
|
||||
queryFilter->setPred(m_pred);
|
||||
queryFilter->m_topTable = m_table;
|
||||
const TableSet& ts2 = m_pred->noInterp();
|
||||
ctx_assert(ts2.size() <= 1);
|
||||
if (ts2.size() == 0) {
|
||||
queryRange->setInterp(m_pred);
|
||||
}
|
||||
deleteScan->setQuery(queryFilter);
|
||||
stmt = deleteScan;
|
||||
} else {
|
||||
ctx_assert(false);
|
||||
}
|
||||
} else {
|
||||
// scan delete with filter
|
||||
Plan_delete_scan* deleteScan = new Plan_delete_scan(m_root);
|
||||
m_root->saveNode(deleteScan);
|
||||
Plan_query_filter* queryFilter = new Plan_query_filter(m_root);
|
||||
m_root->saveNode(queryFilter);
|
||||
Plan_query_scan* queryScan = new Plan_query_scan(m_root);
|
||||
m_root->saveNode(queryScan);
|
||||
queryScan->setTable(m_table);
|
||||
queryScan->setExclusive();
|
||||
queryFilter->setQuery(queryScan);
|
||||
queryFilter->setPred(m_pred);
|
||||
queryFilter->m_topTable = m_table;
|
||||
// interpeter
|
||||
const TableSet& ts2 = m_pred->noInterp();
|
||||
ctx_assert(ts2.size() <= 1);
|
||||
if (ts2.size() == 0) {
|
||||
queryScan->setInterp(m_pred);
|
||||
}
|
||||
deleteScan->setQuery(queryFilter);
|
||||
stmt = deleteScan;
|
||||
}
|
||||
} else {
|
||||
// scan delete without filter
|
||||
Plan_delete_scan* deleteScan = new Plan_delete_scan(m_root);
|
||||
m_root->saveNode(deleteScan);
|
||||
Plan_query_scan* queryScan = new Plan_query_scan(m_root);
|
||||
m_root->saveNode(queryScan);
|
||||
queryScan->setTable(m_table);
|
||||
queryScan->setExclusive();
|
||||
deleteScan->setQuery(queryScan);
|
||||
stmt = deleteScan;
|
||||
}
|
||||
// set base for column position offsets
|
||||
m_table->m_resOff = 1;
|
||||
return stmt;
|
||||
}
|
||||
|
||||
void
|
||||
Plan_delete::describe(Ctx& ctx)
|
||||
{
|
||||
stmtArea().setFunction(ctx, "DELETE WHERE", SQL_DIAG_DELETE_WHERE);
|
||||
}
|
||||
|
||||
Exec_base*
|
||||
Plan_delete::codegen(Ctx& ctx, Ctl& ctl)
|
||||
{
|
||||
ctx_assert(false);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
Plan_delete::print(Ctx& ctx)
|
||||
{
|
||||
ctx.print(" [delete");
|
||||
Plan_base* a[] = { m_table, m_pred };
|
||||
printList(ctx, a, 1);
|
||||
ctx.print("]");
|
||||
}
|
@@ -1,69 +0,0 @@
|
||||
/* Copyright (C) 2003 MySQL AB
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||
|
||||
#ifndef ODBC_CODEGEN_Code_delete_hpp
|
||||
#define ODBC_CODEGEN_Code_delete_hpp
|
||||
|
||||
#include <common/common.hpp>
|
||||
#include "Code_base.hpp"
|
||||
#include "Code_dml.hpp"
|
||||
#include "Code_table.hpp"
|
||||
#include "Code_query.hpp"
|
||||
#include "Code_pred.hpp"
|
||||
|
||||
/**
|
||||
* @class Plan_delete
|
||||
* @brief Delete in PlanTree
|
||||
*/
|
||||
class Plan_delete : public Plan_dml {
|
||||
public:
|
||||
Plan_delete(Plan_root* root);
|
||||
virtual ~Plan_delete();
|
||||
Plan_base* analyze(Ctx& ctx, Ctl& ctl);
|
||||
void describe(Ctx& ctx);
|
||||
Exec_base* codegen(Ctx& ctx, Ctl& ctl);
|
||||
void print(Ctx& ctx);
|
||||
// children
|
||||
void setTable(Plan_table* table);
|
||||
void setPred(Plan_pred* pred);
|
||||
protected:
|
||||
Plan_table* m_table;
|
||||
Plan_pred* m_pred;
|
||||
};
|
||||
|
||||
inline
|
||||
Plan_delete::Plan_delete(Plan_root* root) :
|
||||
Plan_dml(root),
|
||||
m_table(0),
|
||||
m_pred(0)
|
||||
{
|
||||
}
|
||||
|
||||
inline void
|
||||
Plan_delete::setTable(Plan_table* table)
|
||||
{
|
||||
ctx_assert(table != 0);
|
||||
m_table = table;
|
||||
}
|
||||
|
||||
inline void
|
||||
Plan_delete::setPred(Plan_pred* pred)
|
||||
{
|
||||
ctx_assert(pred != 0);
|
||||
m_pred = pred;
|
||||
}
|
||||
|
||||
#endif
|
@@ -1,164 +0,0 @@
|
||||
/* Copyright (C) 2003 MySQL AB
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||
|
||||
#include <common/StmtArea.hpp>
|
||||
#include <dictionary/DictTable.hpp>
|
||||
#include "Code_expr.hpp"
|
||||
#include "Code_delete_index.hpp"
|
||||
#include "Code_table.hpp"
|
||||
#include "Code_root.hpp"
|
||||
|
||||
Plan_delete_index::~Plan_delete_index()
|
||||
{
|
||||
}
|
||||
|
||||
Plan_base*
|
||||
Plan_delete_index::analyze(Ctx& ctx, Ctl& ctl)
|
||||
{
|
||||
ctx_assert(m_query != 0);
|
||||
m_query->analyze(ctx, ctl);
|
||||
if (! ctx.ok())
|
||||
return 0;
|
||||
ctx_assert(m_table != 0);
|
||||
m_table->analyze(ctx, ctl);
|
||||
if (! ctx.ok())
|
||||
return 0;
|
||||
return this;
|
||||
}
|
||||
|
||||
void
|
||||
Plan_delete_index::describe(Ctx& ctx)
|
||||
{
|
||||
stmtArea().setFunction(ctx, "DELETE WHERE", SQL_DIAG_DELETE_WHERE);
|
||||
}
|
||||
|
||||
Exec_base*
|
||||
Plan_delete_index::codegen(Ctx& ctx, Ctl& ctl)
|
||||
{
|
||||
// create code for the query
|
||||
ctx_assert(m_query != 0);
|
||||
Exec_query* execQuery = static_cast<Exec_query*>(m_query->codegen(ctx, ctl));
|
||||
if (! ctx.ok())
|
||||
return 0;
|
||||
ctx_assert(execQuery != 0);
|
||||
// set up
|
||||
ctx_assert(m_table != 0 && m_index != 0);
|
||||
const BaseString& tableName = m_table->getName();
|
||||
ctx_assert(m_index->m_dictIndex != 0);
|
||||
const DictIndex& dictIndex = *m_index->m_dictIndex;
|
||||
const BaseString& indexName = dictIndex.getName();
|
||||
const unsigned keyCount = m_index->m_keyCount;
|
||||
// create the code
|
||||
Exec_delete_index::Code& code = *new Exec_delete_index::Code(keyCount);
|
||||
code.m_tableName = strcpy(new char[tableName.length() + 1], tableName.c_str());
|
||||
code.m_indexName = strcpy(new char[indexName.length() + 1], indexName.c_str());
|
||||
// key attributes
|
||||
code.m_keyId = new NdbAttrId[1 + keyCount];
|
||||
code.m_keyId[0] = (NdbAttrId)-1;
|
||||
for (unsigned k = 1; k <= keyCount; k++) {
|
||||
const DictColumn* keyColumn = dictIndex.getColumn(k);
|
||||
const SqlType& sqlType = keyColumn->sqlType();
|
||||
SqlSpec sqlSpec(sqlType, SqlSpec::Physical);
|
||||
code.m_keySpecs.setEntry(k, sqlSpec);
|
||||
code.m_keyId[k] = k - 1; // index column order
|
||||
}
|
||||
// matching expressions
|
||||
ctx_assert(m_index->m_keyFound);
|
||||
const ExprVector& keyEq = m_index->m_keyEq;
|
||||
ctx_assert(keyEq.size() == 1 + keyCount);
|
||||
code.m_keyMatch = new Exec_expr* [1 + keyCount];
|
||||
code.m_keyMatch[0] = 0;
|
||||
for (unsigned k = 1; k <= keyCount; k++) {
|
||||
Plan_expr* expr = keyEq[k];
|
||||
Exec_expr* execExpr = static_cast<Exec_expr*>(expr->codegen(ctx, ctl));
|
||||
if (! ctx.ok())
|
||||
return 0;
|
||||
ctx_assert(execExpr != 0);
|
||||
code.m_keyMatch[k] = execExpr;
|
||||
}
|
||||
// create the exec
|
||||
Exec_delete_index* exec = new Exec_delete_index(ctl.m_execRoot);
|
||||
ctl.m_execRoot->saveNode(exec);
|
||||
exec->setCode(code);
|
||||
exec->setQuery(execQuery);
|
||||
return exec;
|
||||
}
|
||||
|
||||
void
|
||||
Plan_delete_index::print(Ctx& ctx)
|
||||
{
|
||||
ctx.print(" [delete_index");
|
||||
Plan_base* a[] = { m_query, m_table };
|
||||
printList(ctx, a, 2);
|
||||
ctx.print("]");
|
||||
}
|
||||
|
||||
// Exec_delete_index
|
||||
|
||||
Exec_delete_index::Code::~Code()
|
||||
{
|
||||
delete[] m_tableName;
|
||||
delete[] m_keyId;
|
||||
delete[] m_keyMatch;
|
||||
}
|
||||
|
||||
Exec_delete_index::Data::~Data()
|
||||
{
|
||||
}
|
||||
|
||||
Exec_delete_index::~Exec_delete_index()
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
Exec_delete_index::alloc(Ctx& ctx, Ctl& ctl)
|
||||
{
|
||||
const Code& code = getCode();
|
||||
// allocate the subquery
|
||||
ctx_assert(m_query != 0);
|
||||
m_query->alloc(ctx, ctl);
|
||||
if (! ctx.ok())
|
||||
return;
|
||||
// allocate matching expressions
|
||||
for (unsigned k = 1; k <= code.m_keyCount; k++) {
|
||||
Exec_expr* expr = code.m_keyMatch[k];
|
||||
ctx_assert(expr != 0);
|
||||
expr->alloc(ctx, ctl);
|
||||
if (! ctx.ok())
|
||||
return;
|
||||
}
|
||||
// create data
|
||||
Data& data = *new Data;
|
||||
setData(data);
|
||||
}
|
||||
|
||||
void
|
||||
Exec_delete_index::close(Ctx& ctx)
|
||||
{
|
||||
ctx_assert(m_query != 0);
|
||||
m_query->close(ctx);
|
||||
}
|
||||
|
||||
void
|
||||
Exec_delete_index::print(Ctx& ctx)
|
||||
{
|
||||
const Code& code = getCode();
|
||||
ctx.print(" [delete_index");
|
||||
Exec_base* a[] = { m_query };
|
||||
printList(ctx, a, 1);
|
||||
printList(ctx, (Exec_base**)&code.m_keyMatch[1], code.m_keyCount);
|
||||
ctx.print("]");
|
||||
}
|
@@ -1,156 +0,0 @@
|
||||
/* Copyright (C) 2003 MySQL AB
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||
|
||||
#ifndef ODBC_CODEGEN_Code_delete_index_hpp
|
||||
#define ODBC_CODEGEN_Code_delete_index_hpp
|
||||
|
||||
#include <common/common.hpp>
|
||||
#include "Code_dml.hpp"
|
||||
#include "Code_query.hpp"
|
||||
#include "Code_table.hpp"
|
||||
|
||||
/**
|
||||
* @class Plan_delete_index
|
||||
* @brief Delete by primary key
|
||||
*/
|
||||
class Plan_delete_index : public Plan_dml {
|
||||
public:
|
||||
Plan_delete_index(Plan_root* root);
|
||||
virtual ~Plan_delete_index();
|
||||
Plan_base* analyze(Ctx& ctx, Ctl& ctl);
|
||||
void describe(Ctx& ctx);
|
||||
Exec_base* codegen(Ctx& ctx, Ctl& ctl);
|
||||
void print(Ctx& ctx);
|
||||
// children
|
||||
void setQuery(Plan_query* query);
|
||||
void setTable(Plan_table* table, Plan_table::Index* index);
|
||||
protected:
|
||||
Plan_query* m_query;
|
||||
Plan_table* m_table;
|
||||
Plan_table::Index* m_index;
|
||||
};
|
||||
|
||||
inline
|
||||
Plan_delete_index::Plan_delete_index(Plan_root* root) :
|
||||
Plan_dml(root),
|
||||
m_query(0),
|
||||
m_table(0)
|
||||
{
|
||||
}
|
||||
|
||||
inline void
|
||||
Plan_delete_index::setQuery(Plan_query* query)
|
||||
{
|
||||
ctx_assert(query != 0);
|
||||
m_query = query;
|
||||
}
|
||||
|
||||
inline void
|
||||
Plan_delete_index::setTable(Plan_table* table, Plan_table::Index* index)
|
||||
{
|
||||
ctx_assert(table != 0 && index != 0 && index == &table->m_indexList[index->m_pos] && index->m_pos != 0);
|
||||
m_table = table;
|
||||
m_index = index;
|
||||
}
|
||||
|
||||
/**
|
||||
* @class Exec_delete_index
|
||||
* @brief Delete by primary key
|
||||
*/
|
||||
class Exec_delete_index : public Exec_dml {
|
||||
public:
|
||||
class Code : public Exec_dml::Code {
|
||||
public:
|
||||
Code(unsigned keyCount);
|
||||
virtual ~Code();
|
||||
protected:
|
||||
friend class Plan_delete_index;
|
||||
friend class Exec_delete_index;
|
||||
const char* m_tableName;
|
||||
const char* m_indexName;
|
||||
unsigned m_keyCount;
|
||||
SqlSpecs m_keySpecs; // key types
|
||||
NdbAttrId* m_keyId;
|
||||
Exec_expr** m_keyMatch; // XXX pointers for now
|
||||
};
|
||||
class Data : public Exec_dml::Data {
|
||||
public:
|
||||
Data();
|
||||
virtual ~Data();
|
||||
protected:
|
||||
friend class Exec_delete_index;
|
||||
};
|
||||
Exec_delete_index(Exec_root* root);
|
||||
virtual ~Exec_delete_index();
|
||||
void alloc(Ctx& ctx, Ctl& ctl);
|
||||
void execImpl(Ctx& ctx, Ctl& ctl);
|
||||
void close(Ctx& ctx);
|
||||
void print(Ctx& ctx);
|
||||
// children
|
||||
const Code& getCode() const;
|
||||
Data& getData() const;
|
||||
void setQuery(Exec_query* query);
|
||||
protected:
|
||||
Exec_query* m_query;
|
||||
};
|
||||
|
||||
inline
|
||||
Exec_delete_index::Code::Code(unsigned keyCount) :
|
||||
m_tableName(0),
|
||||
m_indexName(0),
|
||||
m_keyCount(keyCount),
|
||||
m_keySpecs(keyCount),
|
||||
m_keyId(0),
|
||||
m_keyMatch(0)
|
||||
{
|
||||
}
|
||||
|
||||
inline
|
||||
Exec_delete_index::Data::Data()
|
||||
{
|
||||
}
|
||||
|
||||
inline
|
||||
Exec_delete_index::Exec_delete_index(Exec_root* root) :
|
||||
Exec_dml(root),
|
||||
m_query(0)
|
||||
{
|
||||
}
|
||||
|
||||
// children
|
||||
|
||||
inline const Exec_delete_index::Code&
|
||||
Exec_delete_index::getCode() const
|
||||
{
|
||||
const Code* code = static_cast<const Code*>(m_code);
|
||||
return *code;
|
||||
}
|
||||
|
||||
inline Exec_delete_index::Data&
|
||||
Exec_delete_index::getData() const
|
||||
{
|
||||
Data* data = static_cast<Data*>(m_data);
|
||||
return *data;
|
||||
}
|
||||
|
||||
inline void
|
||||
Exec_delete_index::setQuery(Exec_query* query)
|
||||
{
|
||||
ctx_assert(query != 0 && m_query == 0);
|
||||
m_query = query;
|
||||
}
|
||||
|
||||
#endif
|
@@ -1,162 +0,0 @@
|
||||
/* Copyright (C) 2003 MySQL AB
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||
|
||||
#include <common/StmtArea.hpp>
|
||||
#include <dictionary/DictTable.hpp>
|
||||
#include "Code_expr.hpp"
|
||||
#include "Code_delete_lookup.hpp"
|
||||
#include "Code_table.hpp"
|
||||
#include "Code_root.hpp"
|
||||
|
||||
Plan_delete_lookup::~Plan_delete_lookup()
|
||||
{
|
||||
}
|
||||
|
||||
Plan_base*
|
||||
Plan_delete_lookup::analyze(Ctx& ctx, Ctl& ctl)
|
||||
{
|
||||
ctx_assert(m_query != 0);
|
||||
m_query->analyze(ctx, ctl);
|
||||
if (! ctx.ok())
|
||||
return 0;
|
||||
ctx_assert(m_table != 0);
|
||||
m_table->analyze(ctx, ctl);
|
||||
if (! ctx.ok())
|
||||
return 0;
|
||||
return this;
|
||||
}
|
||||
|
||||
void
|
||||
Plan_delete_lookup::describe(Ctx& ctx)
|
||||
{
|
||||
stmtArea().setFunction(ctx, "DELETE WHERE", SQL_DIAG_DELETE_WHERE);
|
||||
}
|
||||
|
||||
Exec_base*
|
||||
Plan_delete_lookup::codegen(Ctx& ctx, Ctl& ctl)
|
||||
{
|
||||
// create code for the query
|
||||
ctx_assert(m_query != 0);
|
||||
Exec_query* execQuery = static_cast<Exec_query*>(m_query->codegen(ctx, ctl));
|
||||
if (! ctx.ok())
|
||||
return 0;
|
||||
ctx_assert(execQuery != 0);
|
||||
// set up
|
||||
ctx_assert(m_table != 0);
|
||||
const BaseString& tableName = m_table->getName();
|
||||
const DictTable& dictTable = m_table->dictTable();
|
||||
const unsigned keyCount = dictTable.keyCount();
|
||||
// create the code
|
||||
Exec_delete_lookup::Code& code = *new Exec_delete_lookup::Code(keyCount);
|
||||
code.m_tableName = strcpy(new char[tableName.length() + 1], tableName.c_str());
|
||||
// key attributes
|
||||
code.m_keyId = new NdbAttrId[1 + keyCount];
|
||||
code.m_keyId[0] = (NdbAttrId)-1;
|
||||
for (unsigned k = 1; k <= keyCount; k++) {
|
||||
const DictColumn* keyColumn = dictTable.getKey(k);
|
||||
const SqlType& sqlType = keyColumn->sqlType();
|
||||
SqlSpec sqlSpec(sqlType, SqlSpec::Physical);
|
||||
code.m_keySpecs.setEntry(k, sqlSpec);
|
||||
code.m_keyId[k] = keyColumn->getAttrId();
|
||||
}
|
||||
// matching expressions
|
||||
const Plan_table::Index& index = m_table->m_indexList[0];
|
||||
ctx_assert(index.m_keyFound);
|
||||
const ExprVector& keyEq = index.m_keyEq;
|
||||
ctx_assert(keyEq.size() == 1 + keyCount);
|
||||
code.m_keyMatch = new Exec_expr* [1 + keyCount];
|
||||
code.m_keyMatch[0] = 0;
|
||||
for (unsigned k = 1; k <= keyCount; k++) {
|
||||
Plan_expr* expr = keyEq[k];
|
||||
Exec_expr* execExpr = static_cast<Exec_expr*>(expr->codegen(ctx, ctl));
|
||||
if (! ctx.ok())
|
||||
return 0;
|
||||
ctx_assert(execExpr != 0);
|
||||
code.m_keyMatch[k] = execExpr;
|
||||
}
|
||||
// create the exec
|
||||
Exec_delete_lookup* exec = new Exec_delete_lookup(ctl.m_execRoot);
|
||||
ctl.m_execRoot->saveNode(exec);
|
||||
exec->setCode(code);
|
||||
exec->setQuery(execQuery);
|
||||
return exec;
|
||||
}
|
||||
|
||||
void
|
||||
Plan_delete_lookup::print(Ctx& ctx)
|
||||
{
|
||||
ctx.print(" [delete_lookup");
|
||||
Plan_base* a[] = { m_query, m_table };
|
||||
printList(ctx, a, 2);
|
||||
ctx.print("]");
|
||||
}
|
||||
|
||||
// Exec_delete_lookup
|
||||
|
||||
Exec_delete_lookup::Code::~Code()
|
||||
{
|
||||
delete[] m_tableName;
|
||||
delete[] m_keyId;
|
||||
delete[] m_keyMatch;
|
||||
}
|
||||
|
||||
Exec_delete_lookup::Data::~Data()
|
||||
{
|
||||
}
|
||||
|
||||
Exec_delete_lookup::~Exec_delete_lookup()
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
Exec_delete_lookup::alloc(Ctx& ctx, Ctl& ctl)
|
||||
{
|
||||
const Code& code = getCode();
|
||||
// allocate the subquery
|
||||
ctx_assert(m_query != 0);
|
||||
m_query->alloc(ctx, ctl);
|
||||
if (! ctx.ok())
|
||||
return;
|
||||
// allocate matching expressions
|
||||
for (unsigned k = 1; k <= code.m_keyCount; k++) {
|
||||
Exec_expr* expr = code.m_keyMatch[k];
|
||||
ctx_assert(expr != 0);
|
||||
expr->alloc(ctx, ctl);
|
||||
if (! ctx.ok())
|
||||
return;
|
||||
}
|
||||
// create data
|
||||
Data& data = *new Data;
|
||||
setData(data);
|
||||
}
|
||||
|
||||
void
|
||||
Exec_delete_lookup::close(Ctx& ctx)
|
||||
{
|
||||
ctx_assert(m_query != 0);
|
||||
m_query->close(ctx);
|
||||
}
|
||||
|
||||
void
|
||||
Exec_delete_lookup::print(Ctx& ctx)
|
||||
{
|
||||
const Code& code = getCode();
|
||||
ctx.print(" [delete_lookup");
|
||||
Exec_base* a[] = { m_query };
|
||||
printList(ctx, a, 1);
|
||||
printList(ctx, (Exec_base**)&code.m_keyMatch[1], code.m_keyCount);
|
||||
ctx.print("]");
|
||||
}
|
@@ -1,152 +0,0 @@
|
||||
/* Copyright (C) 2003 MySQL AB
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||
|
||||
#ifndef ODBC_CODEGEN_Code_delete_lookup_hpp
|
||||
#define ODBC_CODEGEN_Code_delete_lookup_hpp
|
||||
|
||||
#include <common/common.hpp>
|
||||
#include "Code_dml.hpp"
|
||||
#include "Code_query.hpp"
|
||||
#include "Code_table.hpp"
|
||||
|
||||
/**
|
||||
* @class Plan_delete_lookup
|
||||
* @brief Delete by primary key
|
||||
*/
|
||||
class Plan_delete_lookup : public Plan_dml {
|
||||
public:
|
||||
Plan_delete_lookup(Plan_root* root);
|
||||
virtual ~Plan_delete_lookup();
|
||||
Plan_base* analyze(Ctx& ctx, Ctl& ctl);
|
||||
void describe(Ctx& ctx);
|
||||
Exec_base* codegen(Ctx& ctx, Ctl& ctl);
|
||||
void print(Ctx& ctx);
|
||||
// children
|
||||
void setQuery(Plan_query* query);
|
||||
void setTable(Plan_table* table);
|
||||
protected:
|
||||
Plan_query* m_query;
|
||||
Plan_table* m_table;
|
||||
};
|
||||
|
||||
inline
|
||||
Plan_delete_lookup::Plan_delete_lookup(Plan_root* root) :
|
||||
Plan_dml(root),
|
||||
m_query(0),
|
||||
m_table(0)
|
||||
{
|
||||
}
|
||||
|
||||
inline void
|
||||
Plan_delete_lookup::setQuery(Plan_query* query)
|
||||
{
|
||||
ctx_assert(query != 0);
|
||||
m_query = query;
|
||||
}
|
||||
|
||||
inline void
|
||||
Plan_delete_lookup::setTable(Plan_table* table)
|
||||
{
|
||||
ctx_assert(table != 0);
|
||||
m_table = table;
|
||||
}
|
||||
|
||||
/**
|
||||
* @class Exec_delete_lookup
|
||||
* @brief Delete by primary key
|
||||
*/
|
||||
class Exec_delete_lookup : public Exec_dml {
|
||||
public:
|
||||
class Code : public Exec_dml::Code {
|
||||
public:
|
||||
Code(unsigned keyCount);
|
||||
virtual ~Code();
|
||||
protected:
|
||||
friend class Plan_delete_lookup;
|
||||
friend class Exec_delete_lookup;
|
||||
char* m_tableName;
|
||||
unsigned m_keyCount;
|
||||
SqlSpecs m_keySpecs; // key types
|
||||
NdbAttrId* m_keyId;
|
||||
Exec_expr** m_keyMatch; // XXX pointers for now
|
||||
};
|
||||
class Data : public Exec_dml::Data {
|
||||
public:
|
||||
Data();
|
||||
virtual ~Data();
|
||||
protected:
|
||||
friend class Exec_delete_lookup;
|
||||
};
|
||||
Exec_delete_lookup(Exec_root* root);
|
||||
virtual ~Exec_delete_lookup();
|
||||
void alloc(Ctx& ctx, Ctl& ctl);
|
||||
void execImpl(Ctx& ctx, Ctl& ctl);
|
||||
void close(Ctx& ctx);
|
||||
void print(Ctx& ctx);
|
||||
// children
|
||||
const Code& getCode() const;
|
||||
Data& getData() const;
|
||||
void setQuery(Exec_query* query);
|
||||
protected:
|
||||
Exec_query* m_query;
|
||||
};
|
||||
|
||||
inline
|
||||
Exec_delete_lookup::Code::Code(unsigned keyCount) :
|
||||
m_tableName(0),
|
||||
m_keyCount(keyCount),
|
||||
m_keySpecs(keyCount),
|
||||
m_keyId(0),
|
||||
m_keyMatch(0)
|
||||
{
|
||||
}
|
||||
|
||||
inline
|
||||
Exec_delete_lookup::Data::Data()
|
||||
{
|
||||
}
|
||||
|
||||
inline
|
||||
Exec_delete_lookup::Exec_delete_lookup(Exec_root* root) :
|
||||
Exec_dml(root),
|
||||
m_query(0)
|
||||
{
|
||||
}
|
||||
|
||||
// children
|
||||
|
||||
inline const Exec_delete_lookup::Code&
|
||||
Exec_delete_lookup::getCode() const
|
||||
{
|
||||
const Code* code = static_cast<const Code*>(m_code);
|
||||
return *code;
|
||||
}
|
||||
|
||||
inline Exec_delete_lookup::Data&
|
||||
Exec_delete_lookup::getData() const
|
||||
{
|
||||
Data* data = static_cast<Data*>(m_data);
|
||||
return *data;
|
||||
}
|
||||
|
||||
inline void
|
||||
Exec_delete_lookup::setQuery(Exec_query* query)
|
||||
{
|
||||
ctx_assert(query != 0 && m_query == 0);
|
||||
m_query = query;
|
||||
}
|
||||
|
||||
#endif
|
@@ -1,110 +0,0 @@
|
||||
/* Copyright (C) 2003 MySQL AB
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||
|
||||
#include <common/StmtArea.hpp>
|
||||
#include "Code_delete_scan.hpp"
|
||||
#include "Code_root.hpp"
|
||||
|
||||
Plan_delete_scan::~Plan_delete_scan()
|
||||
{
|
||||
}
|
||||
|
||||
Plan_base*
|
||||
Plan_delete_scan::analyze(Ctx& ctx, Ctl& ctl)
|
||||
{
|
||||
ctx_assert(m_query != 0);
|
||||
m_query->analyze(ctx, ctl);
|
||||
if (! ctx.ok())
|
||||
return 0;
|
||||
return this;
|
||||
}
|
||||
|
||||
void
|
||||
Plan_delete_scan::describe(Ctx& ctx)
|
||||
{
|
||||
stmtArea().setFunction(ctx, "DELETE WHERE", SQL_DIAG_DELETE_WHERE);
|
||||
}
|
||||
|
||||
Exec_base*
|
||||
Plan_delete_scan::codegen(Ctx& ctx, Ctl& ctl)
|
||||
{
|
||||
// create code for the subquery
|
||||
ctx_assert(m_query != 0);
|
||||
Exec_query* execQuery = static_cast<Exec_query*>(m_query->codegen(ctx, ctl));
|
||||
if (! ctx.ok())
|
||||
return 0;
|
||||
ctx_assert(execQuery != 0);
|
||||
// create the code
|
||||
Exec_delete_scan* exec = new Exec_delete_scan(ctl.m_execRoot);
|
||||
ctl.m_execRoot->saveNode(exec);
|
||||
Exec_delete_scan::Code& code = *new Exec_delete_scan::Code;
|
||||
exec->setCode(code);
|
||||
exec->setQuery(execQuery);
|
||||
return exec;
|
||||
}
|
||||
|
||||
void
|
||||
Plan_delete_scan::print(Ctx& ctx)
|
||||
{
|
||||
ctx.print(" [delete_scan");
|
||||
Plan_base* a[] = { m_query };
|
||||
printList(ctx, a, 1);
|
||||
ctx.print("]");
|
||||
}
|
||||
|
||||
// Exec_delete_scan
|
||||
|
||||
Exec_delete_scan::Code::~Code()
|
||||
{
|
||||
}
|
||||
|
||||
Exec_delete_scan::Data::~Data()
|
||||
{
|
||||
}
|
||||
|
||||
Exec_delete_scan::~Exec_delete_scan()
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
Exec_delete_scan::alloc(Ctx& ctx, Ctl& ctl)
|
||||
{
|
||||
// allocate the subquery
|
||||
ctx_assert(m_query != 0);
|
||||
m_query->alloc(ctx, ctl);
|
||||
if (! ctx.ok())
|
||||
return;
|
||||
// create data
|
||||
Data& data = *new Data;
|
||||
setData(data);
|
||||
}
|
||||
|
||||
void
|
||||
Exec_delete_scan::close(Ctx& ctx)
|
||||
{
|
||||
ctx_assert(m_query != 0);
|
||||
m_query->close(ctx);
|
||||
}
|
||||
|
||||
void
|
||||
Exec_delete_scan::print(Ctx& ctx)
|
||||
{
|
||||
ctx.print(" [delete_scan");
|
||||
Exec_base* a[] = { m_query };
|
||||
printList(ctx, a, 1);
|
||||
ctx.print("]");
|
||||
}
|
||||
|
@@ -1,130 +0,0 @@
|
||||
/* Copyright (C) 2003 MySQL AB
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||
|
||||
#ifndef ODBC_CODEGEN_Code_delete_scan_hpp
|
||||
#define ODBC_CODEGEN_Code_delete_scan_hpp
|
||||
|
||||
#include <common/common.hpp>
|
||||
#include "Code_dml.hpp"
|
||||
#include "Code_query.hpp"
|
||||
|
||||
/**
|
||||
* @class Plan_delete_scan
|
||||
* @brief Scan delete
|
||||
*/
|
||||
class Plan_delete_scan : public Plan_dml {
|
||||
public:
|
||||
Plan_delete_scan(Plan_root* root);
|
||||
virtual ~Plan_delete_scan();
|
||||
Plan_base* analyze(Ctx& ctx, Ctl& ctl);
|
||||
void describe(Ctx& ctx);
|
||||
Exec_base* codegen(Ctx& ctx, Ctl& ctl);
|
||||
void print(Ctx& ctx);
|
||||
// children
|
||||
void setQuery(Plan_query* query);
|
||||
protected:
|
||||
Plan_query* m_query;
|
||||
};
|
||||
|
||||
inline
|
||||
Plan_delete_scan::Plan_delete_scan(Plan_root* root) :
|
||||
Plan_dml(root),
|
||||
m_query(0)
|
||||
{
|
||||
}
|
||||
|
||||
inline void
|
||||
Plan_delete_scan::setQuery(Plan_query* query)
|
||||
{
|
||||
ctx_assert(query != 0);
|
||||
m_query = query;
|
||||
}
|
||||
|
||||
/**
|
||||
* @class Exec_delete_scan
|
||||
* @brief Scan delete
|
||||
*/
|
||||
class Exec_delete_scan : public Exec_dml {
|
||||
public:
|
||||
class Code : public Exec_dml::Code {
|
||||
public:
|
||||
Code();
|
||||
virtual ~Code();
|
||||
protected:
|
||||
friend class Exec_delete_scan;
|
||||
};
|
||||
class Data : public Exec_dml::Data {
|
||||
public:
|
||||
Data();
|
||||
virtual ~Data();
|
||||
protected:
|
||||
friend class Exec_delete_scan;
|
||||
};
|
||||
Exec_delete_scan(Exec_root* root);
|
||||
virtual ~Exec_delete_scan();
|
||||
void alloc(Ctx& ctx, Ctl& ctl);
|
||||
void execImpl(Ctx& ctx, Ctl& ctl);
|
||||
void close(Ctx& ctx);
|
||||
void print(Ctx& ctx);
|
||||
// children
|
||||
const Code& getCode() const;
|
||||
Data& getData() const;
|
||||
void setQuery(Exec_query* query);
|
||||
protected:
|
||||
Exec_query* m_query;
|
||||
};
|
||||
|
||||
inline
|
||||
Exec_delete_scan::Code::Code()
|
||||
{
|
||||
}
|
||||
|
||||
inline
|
||||
Exec_delete_scan::Data::Data()
|
||||
{
|
||||
}
|
||||
|
||||
inline
|
||||
Exec_delete_scan::Exec_delete_scan(Exec_root* root) :
|
||||
Exec_dml(root),
|
||||
m_query(0)
|
||||
{
|
||||
}
|
||||
|
||||
// children
|
||||
|
||||
inline const Exec_delete_scan::Code&
|
||||
Exec_delete_scan::getCode() const
|
||||
{
|
||||
const Code* code = static_cast<const Code*>(m_code);
|
||||
return *code;
|
||||
}
|
||||
|
||||
inline Exec_delete_scan::Data&
|
||||
Exec_delete_scan::getData() const
|
||||
{
|
||||
Data* data = static_cast<Data*>(m_data);
|
||||
return *data;
|
||||
}
|
||||
|
||||
inline void
|
||||
Exec_delete_scan::setQuery(Exec_query* query)
|
||||
{
|
||||
ctx_assert(query != 0 && m_query == 0);
|
||||
m_query = query;
|
||||
}
|
||||
|
||||
#endif
|
@@ -1,51 +0,0 @@
|
||||
/* Copyright (C) 2003 MySQL AB
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||
|
||||
#include <common/StmtArea.hpp>
|
||||
#include "Code_dml.hpp"
|
||||
|
||||
// Plan_dml
|
||||
|
||||
Plan_dml::~Plan_dml()
|
||||
{
|
||||
}
|
||||
|
||||
// Exec_dml
|
||||
|
||||
Exec_dml::Code::~Code()
|
||||
{
|
||||
}
|
||||
|
||||
Exec_dml::Data::~Data()
|
||||
{
|
||||
}
|
||||
|
||||
Exec_dml::~Exec_dml()
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
Exec_dml::execute(Ctx& ctx, Ctl& ctl)
|
||||
{
|
||||
execImpl(ctx, ctl);
|
||||
if (m_topLevel) {
|
||||
if (ctx.ok()) {
|
||||
if (stmtArea().getRowCount() == 0) {
|
||||
ctx.setCode(SQL_NO_DATA);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,67 +0,0 @@
|
||||
/* Copyright (C) 2003 MySQL AB
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||
|
||||
#ifndef ODBC_CODEGEN_Code_dml_hpp
|
||||
#define ODBC_CODEGEN_Code_dml_hpp
|
||||
|
||||
#include <common/common.hpp>
|
||||
#include <common/ResultArea.hpp>
|
||||
#include "Code_stmt.hpp"
|
||||
|
||||
/**
|
||||
* @class Plan_dml
|
||||
* @brief Base class for DML statements in PlanTree
|
||||
*/
|
||||
class Plan_dml : public Plan_stmt {
|
||||
public:
|
||||
Plan_dml(Plan_root* root);
|
||||
virtual ~Plan_dml() = 0;
|
||||
};
|
||||
|
||||
inline
|
||||
Plan_dml::Plan_dml(Plan_root* root) :
|
||||
Plan_stmt(root)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @class Exec_dml
|
||||
* @brief Base class for DML statements in ExecTree
|
||||
*/
|
||||
class Exec_dml : public Exec_stmt {
|
||||
public:
|
||||
class Code : public Exec_stmt::Code {
|
||||
public:
|
||||
virtual ~Code() = 0;
|
||||
};
|
||||
class Data : public Exec_stmt::Data, public ResultArea {
|
||||
public:
|
||||
virtual ~Data() = 0;
|
||||
};
|
||||
Exec_dml(Exec_root* root);
|
||||
virtual ~Exec_dml() = 0;
|
||||
void execute(Ctx& ctx, Ctl& ctl);
|
||||
protected:
|
||||
virtual void execImpl(Ctx& ctx, Ctl& ctl) = 0;
|
||||
};
|
||||
|
||||
inline
|
||||
Exec_dml::Exec_dml(Exec_root* root) :
|
||||
Exec_stmt(root)
|
||||
{
|
||||
}
|
||||
|
||||
#endif
|
@@ -1,47 +0,0 @@
|
||||
/* Copyright (C) 2003 MySQL AB
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||
|
||||
#include <NdbApi.hpp>
|
||||
#include <common/StmtArea.hpp>
|
||||
#include "Code_dml_column.hpp"
|
||||
|
||||
// Plan_dml_column
|
||||
|
||||
Plan_dml_column::~Plan_dml_column()
|
||||
{
|
||||
}
|
||||
|
||||
Plan_base*
|
||||
Plan_dml_column::analyze(Ctx& ctx, Ctl& ctl)
|
||||
{
|
||||
analyzeColumn(ctx, ctl);
|
||||
if (! ctx.ok())
|
||||
return 0;
|
||||
return this;
|
||||
}
|
||||
|
||||
Exec_base*
|
||||
Plan_dml_column::codegen(Ctx& ctx, Ctl& ctl)
|
||||
{
|
||||
ctx_assert(false);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
Plan_dml_column::print(Ctx& ctx)
|
||||
{
|
||||
ctx.print(" [dml_column %s]", getPrintName());
|
||||
}
|
@@ -1,46 +0,0 @@
|
||||
/* Copyright (C) 2003 MySQL AB
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||
|
||||
#ifndef ODBC_CODEGEN_Code_dml_column_hpp
|
||||
#define ODBC_CODEGEN_Code_dml_column_hpp
|
||||
|
||||
#include <common/common.hpp>
|
||||
#include "Code_column.hpp"
|
||||
|
||||
class DictColumn;
|
||||
class Plan_table;
|
||||
|
||||
/**
|
||||
* @class Plan_dml_column
|
||||
* @brief Column in query expression
|
||||
*/
|
||||
class Plan_dml_column : public Plan_base, public Plan_column {
|
||||
public:
|
||||
Plan_dml_column(Plan_root* root, const BaseString& name);
|
||||
virtual ~Plan_dml_column();
|
||||
Plan_base* analyze(Ctx& ctx, Ctl& ctl);
|
||||
Exec_base* codegen(Ctx& ctx, Ctl& ctl);
|
||||
void print(Ctx& ctx);
|
||||
};
|
||||
|
||||
inline
|
||||
Plan_dml_column::Plan_dml_column(Plan_root* root, const BaseString& name) :
|
||||
Plan_base(root),
|
||||
Plan_column(Type_dml, name)
|
||||
{
|
||||
}
|
||||
|
||||
#endif
|
@@ -1,56 +0,0 @@
|
||||
/* Copyright (C) 2003 MySQL AB
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||
|
||||
#include "Code_dml_row.hpp"
|
||||
#include "Code_dml_column.hpp"
|
||||
|
||||
Plan_dml_row::~Plan_dml_row()
|
||||
{
|
||||
}
|
||||
|
||||
Plan_base*
|
||||
Plan_dml_row::analyze(Ctx& ctx, Ctl& ctl)
|
||||
{
|
||||
unsigned size = getSize();
|
||||
// analyze the columns
|
||||
for (unsigned i = 1; i <= size; i++) {
|
||||
Plan_dml_column* column = getColumn(i);
|
||||
column->analyze(ctx, ctl);
|
||||
if (! ctx.ok())
|
||||
return 0;
|
||||
}
|
||||
// node was not replaced
|
||||
return this;
|
||||
}
|
||||
|
||||
Exec_base*
|
||||
Plan_dml_row::codegen(Ctx& ctx, Ctl& ctl)
|
||||
{
|
||||
ctx_assert(false);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
Plan_dml_row::print(Ctx& ctx)
|
||||
{
|
||||
unsigned size = getSize();
|
||||
ctx.print(" [dml_row");
|
||||
for (unsigned i = 1; i <= size; i++) {
|
||||
Plan_base* a = m_columnList[i];
|
||||
a == 0 ? ctx.print(" -") : a->print(ctx);
|
||||
}
|
||||
ctx.print("]");
|
||||
}
|
@@ -1,76 +0,0 @@
|
||||
/* Copyright (C) 2003 MySQL AB
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||
|
||||
#ifndef ODBC_CODEGEN_Code_dml_row_hpp
|
||||
#define ODBC_CODEGEN_Code_dml_row_hpp
|
||||
|
||||
#include <vector>
|
||||
#include <common/common.hpp>
|
||||
#include <common/DataRow.hpp>
|
||||
#include "Code_base.hpp"
|
||||
#include "Code_dml_column.hpp"
|
||||
|
||||
class Plan_dml_column;
|
||||
|
||||
/**
|
||||
* @class Plan_dml_row
|
||||
* @brief Row of lvalue columns in insert or update
|
||||
*/
|
||||
class Plan_dml_row : public Plan_base {
|
||||
public:
|
||||
Plan_dml_row(Plan_root* root);
|
||||
virtual ~Plan_dml_row();
|
||||
Plan_base* analyze(Ctx& ctx, Ctl& ctl);
|
||||
Exec_base* codegen(Ctx& ctx, Ctl& ctl);
|
||||
void print(Ctx& ctx);
|
||||
// children
|
||||
unsigned getSize() const;
|
||||
void addColumn(Plan_dml_column* column);
|
||||
Plan_dml_column* getColumn(unsigned i) const;
|
||||
protected:
|
||||
DmlColumnVector m_columnList;
|
||||
};
|
||||
|
||||
inline
|
||||
Plan_dml_row::Plan_dml_row(Plan_root* root) :
|
||||
Plan_base(root),
|
||||
m_columnList(1)
|
||||
{
|
||||
}
|
||||
|
||||
// children
|
||||
|
||||
inline unsigned
|
||||
Plan_dml_row::getSize() const
|
||||
{
|
||||
return m_columnList.size() - 1;
|
||||
}
|
||||
|
||||
inline void
|
||||
Plan_dml_row::addColumn(Plan_dml_column* column)
|
||||
{
|
||||
ctx_assert(column != 0);
|
||||
m_columnList.push_back(column);
|
||||
}
|
||||
|
||||
inline Plan_dml_column*
|
||||
Plan_dml_row::getColumn(unsigned i) const
|
||||
{
|
||||
ctx_assert(1 <= i && i <= m_columnList.size() && m_columnList[i] != 0);
|
||||
return m_columnList[i];
|
||||
}
|
||||
|
||||
#endif
|
@@ -1,87 +0,0 @@
|
||||
/* Copyright (C) 2003 MySQL AB
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||
|
||||
#include <common/StmtArea.hpp>
|
||||
#include "Code_drop_index.hpp"
|
||||
#include "Code_root.hpp"
|
||||
|
||||
// Plan_drop_index
|
||||
|
||||
Plan_drop_index::~Plan_drop_index()
|
||||
{
|
||||
}
|
||||
|
||||
Plan_base*
|
||||
Plan_drop_index::analyze(Ctx& ctx, Ctl& ctl)
|
||||
{
|
||||
stmtArea().stmtInfo().setName(Stmt_name_drop_index);
|
||||
return this;
|
||||
}
|
||||
|
||||
void
|
||||
Plan_drop_index::describe(Ctx& ctx)
|
||||
{
|
||||
stmtArea().setFunction(ctx, "DROP INDEX", SQL_DIAG_DROP_INDEX);
|
||||
}
|
||||
|
||||
Exec_base*
|
||||
Plan_drop_index::codegen(Ctx& ctx, Ctl& ctl)
|
||||
{
|
||||
Exec_drop_index* exec = new Exec_drop_index(ctl.m_execRoot);
|
||||
ctl.m_execRoot->saveNode(exec);
|
||||
Exec_drop_index::Code& code = *new Exec_drop_index::Code(m_name, m_tableName);
|
||||
exec->setCode(code);
|
||||
return exec;
|
||||
}
|
||||
|
||||
void
|
||||
Plan_drop_index::print(Ctx& ctx)
|
||||
{
|
||||
ctx.print(" [drop_index %s]", m_name.c_str());
|
||||
}
|
||||
|
||||
// Exec_drop_index
|
||||
|
||||
Exec_drop_index::Code::~Code()
|
||||
{
|
||||
}
|
||||
|
||||
Exec_drop_index::Data::~Data()
|
||||
{
|
||||
}
|
||||
|
||||
Exec_drop_index::~Exec_drop_index()
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
Exec_drop_index::alloc(Ctx& ctx, Ctl& ctl)
|
||||
{
|
||||
Data& data = *new Data;
|
||||
setData(data);
|
||||
}
|
||||
|
||||
void
|
||||
Exec_drop_index::close(Ctx& ctx)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
Exec_drop_index::print(Ctx& ctx)
|
||||
{
|
||||
const Code& code = getCode();
|
||||
ctx.print(" [drop_index %s]", code.m_indexName.c_str());
|
||||
}
|
@@ -1,136 +0,0 @@
|
||||
/* Copyright (C) 2003 MySQL AB
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||
|
||||
#ifndef ODBC_CODEGEN_Code_drop_index_hpp
|
||||
#define ODBC_CODEGEN_Code_drop_index_hpp
|
||||
|
||||
#include <vector>
|
||||
#include <NdbApi.hpp>
|
||||
#include <common/common.hpp>
|
||||
#include "Code_ddl.hpp"
|
||||
|
||||
class DictTable;
|
||||
class DictColumn;
|
||||
|
||||
/**
|
||||
* @class Plan_drop_index
|
||||
* @brief Drop index in PlanTree
|
||||
*/
|
||||
class Plan_drop_index : public Plan_ddl {
|
||||
public:
|
||||
Plan_drop_index(Plan_root* root, const BaseString& name);
|
||||
Plan_drop_index(Plan_root* root, const BaseString& name, const BaseString& tableName);
|
||||
virtual ~Plan_drop_index();
|
||||
Plan_base* analyze(Ctx& ctx, Ctl& ctl);
|
||||
Exec_base* codegen(Ctx& ctx, Ctl& ctl);
|
||||
void describe(Ctx & ctx);
|
||||
void print(Ctx& ctx);
|
||||
// attributes
|
||||
const BaseString& getName() const;
|
||||
protected:
|
||||
BaseString m_name;
|
||||
BaseString m_tableName;
|
||||
};
|
||||
|
||||
inline
|
||||
Plan_drop_index::Plan_drop_index(Plan_root* root, const BaseString& name) :
|
||||
Plan_ddl(root),
|
||||
m_name(name)
|
||||
{
|
||||
}
|
||||
|
||||
inline
|
||||
Plan_drop_index::Plan_drop_index(Plan_root* root, const BaseString& name, const BaseString& tableName) :
|
||||
Plan_ddl(root),
|
||||
m_name(name),
|
||||
m_tableName(tableName)
|
||||
{
|
||||
}
|
||||
|
||||
inline const BaseString&
|
||||
Plan_drop_index::getName() const
|
||||
{
|
||||
return m_name;
|
||||
}
|
||||
|
||||
/**
|
||||
* @class Exec_drop_index
|
||||
* @brief Drop index in ExecTree
|
||||
*/
|
||||
class Exec_drop_index : public Exec_ddl {
|
||||
public:
|
||||
class Code : public Exec_ddl::Code {
|
||||
public:
|
||||
Code(const BaseString& indexName, const BaseString& tableName);
|
||||
virtual ~Code();
|
||||
protected:
|
||||
friend class Exec_drop_index;
|
||||
const BaseString m_indexName;
|
||||
const BaseString m_tableName;
|
||||
};
|
||||
class Data : public Exec_ddl::Data {
|
||||
public:
|
||||
Data();
|
||||
virtual ~Data();
|
||||
protected:
|
||||
friend class Exec_drop_index;
|
||||
};
|
||||
Exec_drop_index(Exec_root* root);
|
||||
virtual ~Exec_drop_index();
|
||||
void alloc(Ctx& ctx, Ctl& ctl);
|
||||
void execute(Ctx& ctx, Ctl& ctl);
|
||||
void close(Ctx& ctx);
|
||||
void print(Ctx& ctx);
|
||||
// children
|
||||
const Code& getCode() const;
|
||||
Data& getData() const;
|
||||
};
|
||||
|
||||
inline
|
||||
Exec_drop_index::Code::Code(const BaseString& indexName, const BaseString& tableName) :
|
||||
m_indexName(indexName),
|
||||
m_tableName(tableName)
|
||||
{
|
||||
}
|
||||
|
||||
inline
|
||||
Exec_drop_index::Data::Data()
|
||||
{
|
||||
}
|
||||
|
||||
inline
|
||||
Exec_drop_index::Exec_drop_index(Exec_root* root) :
|
||||
Exec_ddl(root)
|
||||
{
|
||||
}
|
||||
|
||||
// children
|
||||
|
||||
inline const Exec_drop_index::Code&
|
||||
Exec_drop_index::getCode() const
|
||||
{
|
||||
const Code* code = static_cast<const Code*>(m_code);
|
||||
return *code;
|
||||
}
|
||||
|
||||
inline Exec_drop_index::Data&
|
||||
Exec_drop_index::getData() const
|
||||
{
|
||||
Data* data = static_cast<Data*>(m_data);
|
||||
return *data;
|
||||
}
|
||||
|
||||
#endif
|
@@ -1,87 +0,0 @@
|
||||
/* Copyright (C) 2003 MySQL AB
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||
|
||||
#include <common/StmtArea.hpp>
|
||||
#include "Code_drop_table.hpp"
|
||||
#include "Code_root.hpp"
|
||||
|
||||
// Plan_drop_table
|
||||
|
||||
Plan_drop_table::~Plan_drop_table()
|
||||
{
|
||||
}
|
||||
|
||||
Plan_base*
|
||||
Plan_drop_table::analyze(Ctx& ctx, Ctl& ctl)
|
||||
{
|
||||
stmtArea().stmtInfo().setName(Stmt_name_drop_table);
|
||||
return this;
|
||||
}
|
||||
|
||||
void
|
||||
Plan_drop_table::describe(Ctx& ctx)
|
||||
{
|
||||
stmtArea().setFunction(ctx, "DROP TABLE", SQL_DIAG_DROP_TABLE);
|
||||
}
|
||||
|
||||
Exec_base*
|
||||
Plan_drop_table::codegen(Ctx& ctx, Ctl& ctl)
|
||||
{
|
||||
Exec_drop_table* exec = new Exec_drop_table(ctl.m_execRoot);
|
||||
ctl.m_execRoot->saveNode(exec);
|
||||
Exec_drop_table::Code& code = *new Exec_drop_table::Code(m_name);
|
||||
exec->setCode(code);
|
||||
return exec;
|
||||
}
|
||||
|
||||
void
|
||||
Plan_drop_table::print(Ctx& ctx)
|
||||
{
|
||||
ctx.print(" [drop_table %s]", m_name.c_str());
|
||||
}
|
||||
|
||||
// Exec_drop_table
|
||||
|
||||
Exec_drop_table::Code::~Code()
|
||||
{
|
||||
}
|
||||
|
||||
Exec_drop_table::Data::~Data()
|
||||
{
|
||||
}
|
||||
|
||||
Exec_drop_table::~Exec_drop_table()
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
Exec_drop_table::alloc(Ctx& ctx, Ctl& ctl)
|
||||
{
|
||||
Data& data = *new Data;
|
||||
setData(data);
|
||||
}
|
||||
|
||||
void
|
||||
Exec_drop_table::close(Ctx& ctx)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
Exec_drop_table::print(Ctx& ctx)
|
||||
{
|
||||
const Code& code = getCode();
|
||||
ctx.print(" [drop_table %s]", code.m_tableName.c_str());
|
||||
}
|
@@ -1,124 +0,0 @@
|
||||
/* Copyright (C) 2003 MySQL AB
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||
|
||||
#ifndef ODBC_CODEGEN_Code_drop_table_hpp
|
||||
#define ODBC_CODEGEN_Code_drop_table_hpp
|
||||
|
||||
#include <vector>
|
||||
#include <NdbApi.hpp>
|
||||
#include <common/common.hpp>
|
||||
#include "Code_ddl.hpp"
|
||||
|
||||
class DictTable;
|
||||
class DictColumn;
|
||||
|
||||
/**
|
||||
* @class Plan_drop_table
|
||||
* @brief Drop table in PlanTree
|
||||
*/
|
||||
class Plan_drop_table : public Plan_ddl {
|
||||
public:
|
||||
Plan_drop_table(Plan_root* root, const BaseString& name);
|
||||
virtual ~Plan_drop_table();
|
||||
Plan_base* analyze(Ctx& ctx, Ctl& ctl);
|
||||
Exec_base* codegen(Ctx& ctx, Ctl& ctl);
|
||||
void describe(Ctx & ctx);
|
||||
void print(Ctx& ctx);
|
||||
// attributes
|
||||
const BaseString& getName() const;
|
||||
protected:
|
||||
BaseString m_name;
|
||||
};
|
||||
|
||||
inline
|
||||
Plan_drop_table::Plan_drop_table(Plan_root* root, const BaseString& name) :
|
||||
Plan_ddl(root),
|
||||
m_name(name)
|
||||
{
|
||||
}
|
||||
|
||||
inline const BaseString&
|
||||
Plan_drop_table::getName() const
|
||||
{
|
||||
return m_name;
|
||||
}
|
||||
|
||||
/**
|
||||
* @class Exec_drop_table
|
||||
* @brief Drop table in ExecTree
|
||||
*/
|
||||
class Exec_drop_table : public Exec_ddl {
|
||||
public:
|
||||
class Code : public Exec_ddl::Code {
|
||||
public:
|
||||
Code(const BaseString& tableName);
|
||||
virtual ~Code();
|
||||
protected:
|
||||
friend class Exec_drop_table;
|
||||
const BaseString m_tableName;
|
||||
};
|
||||
class Data : public Exec_ddl::Data {
|
||||
public:
|
||||
Data();
|
||||
virtual ~Data();
|
||||
protected:
|
||||
friend class Exec_drop_table;
|
||||
};
|
||||
Exec_drop_table(Exec_root* root);
|
||||
virtual ~Exec_drop_table();
|
||||
void alloc(Ctx& ctx, Ctl& ctl);
|
||||
void execute(Ctx& ctx, Ctl& ctl);
|
||||
void close(Ctx& ctx);
|
||||
void print(Ctx& ctx);
|
||||
// children
|
||||
const Code& getCode() const;
|
||||
Data& getData() const;
|
||||
};
|
||||
|
||||
inline
|
||||
Exec_drop_table::Code::Code(const BaseString& tableName) :
|
||||
m_tableName(tableName)
|
||||
{
|
||||
}
|
||||
|
||||
inline
|
||||
Exec_drop_table::Data::Data()
|
||||
{
|
||||
}
|
||||
|
||||
inline
|
||||
Exec_drop_table::Exec_drop_table(Exec_root* root) :
|
||||
Exec_ddl(root)
|
||||
{
|
||||
}
|
||||
|
||||
// children
|
||||
|
||||
inline const Exec_drop_table::Code&
|
||||
Exec_drop_table::getCode() const
|
||||
{
|
||||
const Code* code = static_cast<const Code*>(m_code);
|
||||
return *code;
|
||||
}
|
||||
|
||||
inline Exec_drop_table::Data&
|
||||
Exec_drop_table::getData() const
|
||||
{
|
||||
Data* data = static_cast<Data*>(m_data);
|
||||
return *data;
|
||||
}
|
||||
|
||||
#endif
|
@@ -1,79 +0,0 @@
|
||||
/* Copyright (C) 2003 MySQL AB
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||
|
||||
#include "Code_expr.hpp"
|
||||
#include "Code_expr_row.hpp"
|
||||
|
||||
// Plan_expr
|
||||
|
||||
Plan_expr::~Plan_expr()
|
||||
{
|
||||
}
|
||||
|
||||
bool
|
||||
Plan_expr::isEqual(const Plan_expr* expr) const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
Plan_expr::isAnyEqual(const Plan_expr_row* row) const
|
||||
{
|
||||
ctx_assert(row != 0);
|
||||
const unsigned size = row->getSize();
|
||||
for (unsigned i = 1; i <= size; i++) {
|
||||
if (isEqual(row->getExpr(i)))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
Plan_expr::isGroupBy(const Plan_expr_row* row) const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Exec_expr
|
||||
|
||||
Exec_expr::Code::~Code()
|
||||
{
|
||||
}
|
||||
|
||||
Exec_expr::Data::~Data()
|
||||
{
|
||||
}
|
||||
|
||||
Exec_expr::~Exec_expr()
|
||||
{
|
||||
}
|
||||
|
||||
SqlField&
|
||||
Exec_expr::Data::groupField(const SqlType& sqlType, unsigned i, bool initFlag)
|
||||
{
|
||||
if (m_groupField.size() == 0) {
|
||||
m_groupField.resize(1);
|
||||
}
|
||||
if (initFlag) {
|
||||
//unsigned i2 = m_groupField.size();
|
||||
//ctx_assert(i == i2);
|
||||
const SqlSpec sqlSpec(sqlType, SqlSpec::Physical);
|
||||
const SqlField sqlField(sqlSpec);
|
||||
m_groupField.push_back(sqlField);
|
||||
}
|
||||
ctx_assert(i != 0 && i < m_groupField.size());
|
||||
return m_groupField[i];
|
||||
}
|
@@ -1,219 +0,0 @@
|
||||
/* Copyright (C) 2003 MySQL AB
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||
|
||||
#ifndef ODBC_CODEGEN_Code_expr_hpp
|
||||
#define ODBC_CODEGEN_Code_expr_hpp
|
||||
|
||||
#include <common/common.hpp>
|
||||
#include <common/DataField.hpp>
|
||||
#include "Code_base.hpp"
|
||||
|
||||
class Ctx;
|
||||
class Plan_expr_row;
|
||||
class Exec_expr;
|
||||
|
||||
/**
|
||||
* @class Plan_expr
|
||||
* @brief Base class for expressions in PlanTree
|
||||
*/
|
||||
class Plan_expr : public Plan_base {
|
||||
public:
|
||||
// type is convenient since RTTI cannot be used
|
||||
enum Type {
|
||||
TypeUndefined = 0,
|
||||
TypeColumn,
|
||||
TypeConst,
|
||||
TypeConv,
|
||||
TypeFunc,
|
||||
TypeOp,
|
||||
TypeParam,
|
||||
TypeValue
|
||||
};
|
||||
Plan_expr(Plan_root* root, Type type);
|
||||
virtual ~Plan_expr() = 0;
|
||||
Type type() const;
|
||||
const SqlType& sqlType() const; // data type set by analyze
|
||||
const TableSet& tableSet() const;
|
||||
const BaseString& getAlias() const;
|
||||
bool isAggr() const;
|
||||
bool isBound() const;
|
||||
bool isAnyEqual(const Plan_expr_row* row) const;
|
||||
virtual bool isEqual(const Plan_expr* expr) const;
|
||||
virtual bool isGroupBy(const Plan_expr_row* row) const;
|
||||
protected:
|
||||
friend class Plan_expr_row;
|
||||
friend class Plan_expr_op;
|
||||
friend class Plan_expr_func;
|
||||
friend class Plan_comp_op;
|
||||
const Type m_type;
|
||||
SqlType m_sqlType; // subclass must set
|
||||
BaseString m_alias; // for row expression alias
|
||||
TableSet m_tableSet; // depends on these tables
|
||||
bool m_isAggr; // contains an aggregate expression
|
||||
bool m_isBound; // only constants and aggregates
|
||||
Exec_expr* m_exec; // XXX wrong move
|
||||
};
|
||||
|
||||
inline
|
||||
Plan_expr::Plan_expr(Plan_root* root, Type type) :
|
||||
Plan_base(root),
|
||||
m_type(type),
|
||||
m_isAggr(false),
|
||||
m_isBound(false),
|
||||
m_exec(0)
|
||||
{
|
||||
}
|
||||
|
||||
inline Plan_expr::Type
|
||||
Plan_expr::type() const
|
||||
{
|
||||
return m_type;
|
||||
}
|
||||
|
||||
inline const SqlType&
|
||||
Plan_expr::sqlType() const
|
||||
{
|
||||
ctx_assert(m_sqlType.type() != SqlType::Undef);
|
||||
return m_sqlType;
|
||||
}
|
||||
|
||||
inline const Plan_base::TableSet&
|
||||
Plan_expr::tableSet() const
|
||||
{
|
||||
return m_tableSet;
|
||||
}
|
||||
|
||||
inline const BaseString&
|
||||
Plan_expr::getAlias() const
|
||||
{
|
||||
return m_alias;
|
||||
}
|
||||
|
||||
inline bool
|
||||
Plan_expr::isAggr() const
|
||||
{
|
||||
return m_isAggr;
|
||||
}
|
||||
|
||||
inline bool
|
||||
Plan_expr::isBound() const
|
||||
{
|
||||
return m_isBound;
|
||||
}
|
||||
|
||||
/**
|
||||
* @class Exec_expr
|
||||
* @brief Base class for expressions in ExecTree
|
||||
*/
|
||||
class Exec_expr : public Exec_base {
|
||||
public:
|
||||
/**
|
||||
* Exec_expr::Code includes reference to SqlSpec which
|
||||
* specifies data type and access method.
|
||||
*/
|
||||
class Code : public Exec_base::Code {
|
||||
public:
|
||||
Code(const SqlSpec& sqlSpec);
|
||||
virtual ~Code() = 0;
|
||||
const SqlSpec& sqlSpec() const;
|
||||
protected:
|
||||
friend class Exec_expr;
|
||||
const SqlSpec& m_sqlSpec; // subclass must contain
|
||||
};
|
||||
/**
|
||||
* Exec_expr::Data includes reference to SqlField which
|
||||
* contains specification and data address.
|
||||
*/
|
||||
class Data : public Exec_base::Data {
|
||||
public:
|
||||
Data(const SqlField& sqlField);
|
||||
virtual ~Data() = 0;
|
||||
const SqlField& sqlField() const;
|
||||
const SqlField& groupField(unsigned i) const;
|
||||
protected:
|
||||
friend class Exec_expr;
|
||||
const SqlField& m_sqlField; // subclass must contain
|
||||
// group-by data
|
||||
typedef std::vector<SqlField> GroupField;
|
||||
GroupField m_groupField;
|
||||
SqlField& groupField(const SqlType& sqlType, unsigned i, bool initFlag);
|
||||
};
|
||||
Exec_expr(Exec_root* root);
|
||||
virtual ~Exec_expr() = 0;
|
||||
/**
|
||||
* Evaluate the expression. Must be implemented by all
|
||||
* subclasses. Check ctx.ok() for errors.
|
||||
*/
|
||||
virtual void evaluate(Ctx& ctx, Ctl& ctl) = 0;
|
||||
// children
|
||||
const Code& getCode() const;
|
||||
Data& getData() const;
|
||||
};
|
||||
|
||||
inline
|
||||
Exec_expr::Code::Code(const SqlSpec& sqlSpec) :
|
||||
m_sqlSpec(sqlSpec)
|
||||
{
|
||||
}
|
||||
|
||||
inline const SqlSpec&
|
||||
Exec_expr::Code::sqlSpec() const {
|
||||
return m_sqlSpec;
|
||||
}
|
||||
|
||||
inline
|
||||
Exec_expr::Data::Data(const SqlField& sqlField) :
|
||||
m_sqlField(sqlField)
|
||||
{
|
||||
}
|
||||
|
||||
inline const SqlField&
|
||||
Exec_expr::Data::sqlField() const
|
||||
{
|
||||
return m_sqlField;
|
||||
}
|
||||
|
||||
inline const SqlField&
|
||||
Exec_expr::Data::groupField(unsigned i) const
|
||||
{
|
||||
ctx_assert(i != 0 && i < m_groupField.size());
|
||||
return m_groupField[i];
|
||||
}
|
||||
|
||||
inline
|
||||
Exec_expr::Exec_expr(Exec_root* root) :
|
||||
Exec_base(root)
|
||||
{
|
||||
}
|
||||
|
||||
// children
|
||||
|
||||
inline const Exec_expr::Code&
|
||||
Exec_expr::getCode() const
|
||||
{
|
||||
const Code* code = static_cast<const Code*>(m_code);
|
||||
return *code;
|
||||
}
|
||||
|
||||
inline Exec_expr::Data&
|
||||
Exec_expr::getData() const
|
||||
{
|
||||
Data* data = static_cast<Data*>(m_data);
|
||||
return *data;
|
||||
}
|
||||
|
||||
|
||||
#endif
|
@@ -1,160 +0,0 @@
|
||||
/* Copyright (C) 2003 MySQL AB
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||
|
||||
#include <NdbApi.hpp>
|
||||
#include <common/StmtArea.hpp>
|
||||
#include <dictionary/DictSchema.hpp>
|
||||
#include <dictionary/DictColumn.hpp>
|
||||
#include "Code_query.hpp"
|
||||
#include "Code_table.hpp"
|
||||
#include "Code_expr_column.hpp"
|
||||
#include "Code_root.hpp"
|
||||
|
||||
// Plan_expr_column
|
||||
|
||||
Plan_expr_column::~Plan_expr_column()
|
||||
{
|
||||
}
|
||||
|
||||
Plan_base*
|
||||
Plan_expr_column::analyze(Ctx& ctx, Ctl& ctl)
|
||||
{
|
||||
m_exec = 0;
|
||||
analyzeColumn(ctx, ctl);
|
||||
if (! ctx.ok())
|
||||
return 0;
|
||||
Plan_expr::m_sqlType = Plan_column::m_sqlType;
|
||||
// depends on one table
|
||||
m_tableSet.insert(m_resTable);
|
||||
// not constant as set-value
|
||||
ctl.m_const = false;
|
||||
// set alias name
|
||||
m_alias = m_name;
|
||||
return this;
|
||||
}
|
||||
|
||||
Exec_base*
|
||||
Plan_expr_column::codegen(Ctx& ctx, Ctl& ctl)
|
||||
{
|
||||
if (m_exec != 0)
|
||||
return m_exec;
|
||||
// connect column to query column
|
||||
const Exec_query* execQuery = ctl.m_execQuery;
|
||||
ctx_assert(execQuery != 0);
|
||||
const Exec_query::Code& codeQuery = execQuery->getCode();
|
||||
const SqlSpec sqlSpec(Plan_expr::m_sqlType, SqlSpec::Reference);
|
||||
// offset in final output row
|
||||
ctx_assert(m_resTable != 0 && m_resTable->m_resOff != 0 && m_resPos != 0);
|
||||
unsigned resOff = m_resTable->m_resOff + (m_resPos - 1);
|
||||
// create the code
|
||||
Exec_expr_column* exec = new Exec_expr_column(ctl.m_execRoot);
|
||||
ctl.m_execRoot->saveNode(exec);
|
||||
Exec_expr_column::Code& code = *new Exec_expr_column::Code(sqlSpec, resOff);
|
||||
exec->setCode(code);
|
||||
m_exec = exec;
|
||||
return exec;
|
||||
}
|
||||
|
||||
bool
|
||||
Plan_expr_column::resolveEq(Ctx& ctx, Plan_expr* expr)
|
||||
{
|
||||
ctx_assert(m_resTable != 0 && expr != 0);
|
||||
return m_resTable->resolveEq(ctx, this, expr);
|
||||
}
|
||||
|
||||
void
|
||||
Plan_expr_column::print(Ctx& ctx)
|
||||
{
|
||||
ctx.print(" [expr_column %s]", getPrintName());
|
||||
}
|
||||
|
||||
bool
|
||||
Plan_expr_column::isEqual(const Plan_expr* expr) const
|
||||
{
|
||||
ctx_assert(expr != 0);
|
||||
if (expr->type() != Plan_expr::TypeColumn)
|
||||
return false;
|
||||
const Plan_expr_column* expr2 = static_cast<const Plan_expr_column*>(expr);
|
||||
ctx_assert(m_resTable != 0 && expr2->m_resTable != 0);
|
||||
if (m_resTable != expr2->m_resTable)
|
||||
return false;
|
||||
ctx_assert(m_dictColumn != 0 && expr2->m_dictColumn != 0);
|
||||
if (m_dictColumn != expr2->m_dictColumn)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
Plan_expr_column::isGroupBy(const Plan_expr_row* row) const
|
||||
{
|
||||
if (isAnyEqual(row))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
// Exec_expr_column
|
||||
|
||||
Exec_expr_column::Code::~Code()
|
||||
{
|
||||
}
|
||||
|
||||
Exec_expr_column::Data::~Data()
|
||||
{
|
||||
}
|
||||
|
||||
Exec_expr_column::~Exec_expr_column()
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
Exec_expr_column::alloc(Ctx& ctx, Ctl& ctl)
|
||||
{
|
||||
if (m_data != 0)
|
||||
return;
|
||||
const Code& code = getCode();
|
||||
// connect column to query column
|
||||
ctx_assert(ctl.m_query != 0);
|
||||
const SqlRow& sqlRow = ctl.m_query->getData().sqlRow();
|
||||
SqlField& sqlField = sqlRow.getEntry(code.m_resOff);
|
||||
// create the data
|
||||
Data& data = *new Data(sqlField);
|
||||
setData(data);
|
||||
}
|
||||
|
||||
void
|
||||
Exec_expr_column::evaluate(Ctx& ctx, Ctl& ctl)
|
||||
{
|
||||
const Code& code = getCode();
|
||||
Data& data = getData();
|
||||
if (ctl.m_groupIndex != 0) {
|
||||
SqlField& out = data.groupField(code.sqlSpec().sqlType(), ctl.m_groupIndex, ctl.m_groupInit);
|
||||
data.sqlField().copy(ctx, out);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Exec_expr_column::close(Ctx& ctx)
|
||||
{
|
||||
Data& data = getData();
|
||||
data.m_groupField.clear();
|
||||
}
|
||||
|
||||
void
|
||||
Exec_expr_column::print(Ctx& ctx)
|
||||
{
|
||||
const Code& code = getCode();
|
||||
ctx.print(" [column %d]", code.m_resOff);
|
||||
}
|
@@ -1,120 +0,0 @@
|
||||
/* Copyright (C) 2003 MySQL AB
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||
|
||||
#ifndef ODBC_CODEGEN_Code_expr_column_hpp
|
||||
#define ODBC_CODEGEN_Code_expr_column_hpp
|
||||
|
||||
#include <common/common.hpp>
|
||||
#include "Code_column.hpp"
|
||||
#include "Code_expr.hpp"
|
||||
|
||||
class DictColumn;
|
||||
class Plan_table;
|
||||
|
||||
/**
|
||||
* @class Plan_expr_column
|
||||
* @brief Column in query expression
|
||||
*/
|
||||
class Plan_expr_column : public Plan_expr, public Plan_column {
|
||||
public:
|
||||
Plan_expr_column(Plan_root* root, const BaseString& name);
|
||||
virtual ~Plan_expr_column();
|
||||
Plan_base* analyze(Ctx& ctx, Ctl& ctl);
|
||||
Exec_base* codegen(Ctx& ctx, Ctl& ctl);
|
||||
bool resolveEq(Ctx& ctx, Plan_expr* expr);
|
||||
void print(Ctx& ctx);
|
||||
bool isEqual(const Plan_expr* expr) const;
|
||||
bool isGroupBy(const Plan_expr_row* row) const;
|
||||
};
|
||||
|
||||
inline
|
||||
Plan_expr_column::Plan_expr_column(Plan_root* root, const BaseString& name) :
|
||||
Plan_expr(root, TypeColumn),
|
||||
Plan_column(Type_expr, name)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @class Exec_expr_column
|
||||
* @brief Column in query expression
|
||||
*/
|
||||
class Exec_expr_column : public Exec_expr {
|
||||
public:
|
||||
class Code : public Exec_expr::Code {
|
||||
public:
|
||||
Code(const SqlSpec& sqlSpec, unsigned resOff);
|
||||
virtual ~Code();
|
||||
protected:
|
||||
friend class Exec_expr_column;
|
||||
SqlSpec m_sqlSpec;
|
||||
unsigned m_resOff;
|
||||
};
|
||||
class Data : public Exec_expr::Data {
|
||||
public:
|
||||
Data(SqlField& sqlField);
|
||||
virtual ~Data();
|
||||
protected:
|
||||
friend class Exec_expr_column;
|
||||
// set reference to SqlField in query
|
||||
};
|
||||
Exec_expr_column(Exec_root* root);
|
||||
virtual ~Exec_expr_column();
|
||||
void alloc(Ctx& ctx, Ctl& ctl);
|
||||
void evaluate(Ctx& ctx, Ctl& ctl);
|
||||
void close(Ctx& ctx);
|
||||
void print(Ctx& ctx);
|
||||
// children
|
||||
const Code& getCode() const;
|
||||
Data& getData() const;
|
||||
};
|
||||
|
||||
inline
|
||||
Exec_expr_column::Code::Code(const SqlSpec& sqlSpec, unsigned resOff) :
|
||||
Exec_expr::Code(m_sqlSpec),
|
||||
m_sqlSpec(sqlSpec),
|
||||
m_resOff(resOff)
|
||||
{
|
||||
}
|
||||
|
||||
inline
|
||||
Exec_expr_column::Data::Data(SqlField& sqlField) :
|
||||
Exec_expr::Data(sqlField)
|
||||
{
|
||||
}
|
||||
|
||||
inline
|
||||
Exec_expr_column::Exec_expr_column(Exec_root* root) :
|
||||
Exec_expr(root)
|
||||
{
|
||||
}
|
||||
|
||||
// children
|
||||
|
||||
inline const Exec_expr_column::Code&
|
||||
Exec_expr_column::getCode() const
|
||||
{
|
||||
const Code* code = static_cast<const Code*>(m_code);
|
||||
return *code;
|
||||
}
|
||||
|
||||
inline Exec_expr_column::Data&
|
||||
Exec_expr_column::getData() const
|
||||
{
|
||||
Data* data = static_cast<Data*>(m_data);
|
||||
return *data;
|
||||
}
|
||||
|
||||
#endif
|
@@ -1,138 +0,0 @@
|
||||
/* Copyright (C) 2003 MySQL AB
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||
|
||||
#include "Code_expr_const.hpp"
|
||||
#include "Code_root.hpp"
|
||||
|
||||
// Plan_expr_const
|
||||
|
||||
Plan_expr_const::~Plan_expr_const()
|
||||
{
|
||||
}
|
||||
|
||||
Plan_base*
|
||||
Plan_expr_const::analyze(Ctx& ctx, Ctl& ctl)
|
||||
{
|
||||
m_exec = 0;
|
||||
// convert data type
|
||||
m_lexType.convert(ctx, m_sqlType, m_string.length());
|
||||
if (! ctx.ok())
|
||||
return 0;
|
||||
// depends on no tables
|
||||
// set alias name
|
||||
m_alias = m_string;
|
||||
// node was not changed
|
||||
return this;
|
||||
}
|
||||
|
||||
Exec_base*
|
||||
Plan_expr_const::codegen(Ctx& ctx, Ctl& ctl)
|
||||
{
|
||||
if (m_exec != 0)
|
||||
return m_exec;
|
||||
// convert data
|
||||
SqlSpec sqlSpec(m_sqlType, SqlSpec::Physical);
|
||||
SqlField sqlField(sqlSpec);
|
||||
LexSpec lexSpec(m_lexType);
|
||||
lexSpec.convert(ctx, m_string, sqlField);
|
||||
if (! ctx.ok())
|
||||
return 0;
|
||||
// create code
|
||||
Exec_expr_const* exec = new Exec_expr_const(ctl.m_execRoot);
|
||||
ctl.m_execRoot->saveNode(exec);
|
||||
Exec_expr_const::Code& code = *new Exec_expr_const::Code(sqlField);
|
||||
exec->setCode(code);
|
||||
m_exec = exec;
|
||||
return exec;
|
||||
}
|
||||
|
||||
void
|
||||
Plan_expr_const::print(Ctx& ctx)
|
||||
{
|
||||
ctx.print(" [const %s]", m_string.c_str());
|
||||
}
|
||||
|
||||
bool
|
||||
Plan_expr_const::isEqual(const Plan_expr* expr) const
|
||||
{
|
||||
ctx_assert(expr != 0);
|
||||
if (expr->type() != Plan_expr::TypeConst)
|
||||
return false;
|
||||
const Plan_expr_const* expr2 = static_cast<const Plan_expr_const*>(expr);
|
||||
if (strcmp(m_string.c_str(), expr2->m_string.c_str()) != 0)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
Plan_expr_const::isGroupBy(const Plan_expr_row* row) const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
// Exec_expr_const
|
||||
|
||||
Exec_expr_const::Code::~Code()
|
||||
{
|
||||
}
|
||||
|
||||
Exec_expr_const::Data::~Data()
|
||||
{
|
||||
}
|
||||
|
||||
Exec_expr_const::~Exec_expr_const()
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
Exec_expr_const::alloc(Ctx& ctx, Ctl& ctl)
|
||||
{
|
||||
if (m_data != 0)
|
||||
return;
|
||||
// copy the value for const correctness reasons
|
||||
SqlField sqlField(getCode().m_sqlField);
|
||||
Data& data = *new Data(sqlField);
|
||||
setData(data);
|
||||
}
|
||||
|
||||
void
|
||||
Exec_expr_const::evaluate(Ctx& ctx, Ctl& ctl)
|
||||
{
|
||||
const Code& code = getCode();
|
||||
Data& data = getData();
|
||||
if (ctl.m_groupIndex != 0) {
|
||||
SqlField& out = data.groupField(code.sqlSpec().sqlType(), ctl.m_groupIndex, ctl.m_groupInit);
|
||||
data.sqlField().copy(ctx, out);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Exec_expr_const::close(Ctx& ctx)
|
||||
{
|
||||
Data& data = getData();
|
||||
data.m_groupField.clear();
|
||||
}
|
||||
|
||||
void
|
||||
Exec_expr_const::print(Ctx& ctx)
|
||||
{
|
||||
const Code& code = getCode();
|
||||
ctx.print(" [");
|
||||
char buf[500];
|
||||
code.m_sqlField.print(buf, sizeof(buf));
|
||||
ctx.print("%s", buf);
|
||||
ctx.print("]");
|
||||
}
|
@@ -1,120 +0,0 @@
|
||||
/* Copyright (C) 2003 MySQL AB
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||
|
||||
#ifndef ODBC_CODEGEN_Code_expr_const_hpp
|
||||
#define ODBC_CODEGEN_Code_expr_const_hpp
|
||||
|
||||
#include <common/common.hpp>
|
||||
#include <common/DataField.hpp>
|
||||
#include "Code_expr.hpp"
|
||||
|
||||
/**
|
||||
* @class Plan_expr_const
|
||||
* @brief Constant expression value in PlanTree
|
||||
*/
|
||||
class Plan_expr_const : public Plan_expr {
|
||||
public:
|
||||
Plan_expr_const(Plan_root* root, LexType lexType, const char* value);
|
||||
virtual ~Plan_expr_const();
|
||||
Plan_base* analyze(Ctx& ctx, Ctl& ctl);
|
||||
Exec_base* codegen(Ctx& ctx, Ctl& ctl);
|
||||
void print(Ctx& ctx);
|
||||
bool isEqual(const Plan_expr* expr) const;
|
||||
bool isGroupBy(const Plan_expr_row* row) const;
|
||||
protected:
|
||||
// lexical type and token set by the parser
|
||||
LexType m_lexType;
|
||||
BaseString m_string;
|
||||
};
|
||||
|
||||
inline
|
||||
Plan_expr_const::Plan_expr_const(Plan_root* root, LexType lexType, const char* value) :
|
||||
Plan_expr(root, TypeConst),
|
||||
m_lexType(lexType),
|
||||
m_string(value)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @class Exec_expr_const
|
||||
* @brief Constant expression value in ExecTree
|
||||
*/
|
||||
class Exec_expr_const : public Exec_expr {
|
||||
public:
|
||||
class Code : public Exec_expr::Code {
|
||||
public:
|
||||
Code(const SqlField& sqlField);
|
||||
virtual ~Code();
|
||||
protected:
|
||||
friend class Exec_expr_const;
|
||||
const SqlField m_sqlField;
|
||||
};
|
||||
class Data : public Exec_expr::Data {
|
||||
public:
|
||||
Data(SqlField& sqlField);
|
||||
virtual ~Data();
|
||||
protected:
|
||||
friend class Exec_expr_const;
|
||||
SqlField m_sqlField;
|
||||
};
|
||||
Exec_expr_const(Exec_root* root);
|
||||
virtual ~Exec_expr_const();
|
||||
void alloc(Ctx& ctx, Ctl& ctl);
|
||||
void evaluate(Ctx& ctx, Ctl& ctl);
|
||||
void close(Ctx& ctx);
|
||||
void print(Ctx& ctx);
|
||||
// children
|
||||
const Code& getCode() const;
|
||||
Data& getData() const;
|
||||
};
|
||||
|
||||
inline
|
||||
Exec_expr_const::Code::Code(const SqlField& sqlField) :
|
||||
Exec_expr::Code(m_sqlField.sqlSpec()),
|
||||
m_sqlField(sqlField)
|
||||
{
|
||||
}
|
||||
|
||||
inline
|
||||
Exec_expr_const::Data::Data(SqlField& sqlField) :
|
||||
Exec_expr::Data(m_sqlField),
|
||||
m_sqlField(sqlField)
|
||||
{
|
||||
}
|
||||
|
||||
inline
|
||||
Exec_expr_const::Exec_expr_const(Exec_root* root) :
|
||||
Exec_expr(root)
|
||||
{
|
||||
}
|
||||
|
||||
// children
|
||||
|
||||
inline const Exec_expr_const::Code&
|
||||
Exec_expr_const::getCode() const
|
||||
{
|
||||
const Code* code = static_cast<const Code*>(m_code);
|
||||
return *code;
|
||||
}
|
||||
|
||||
inline Exec_expr_const::Data&
|
||||
Exec_expr_const::getData() const
|
||||
{
|
||||
Data* data = static_cast<Data*>(m_data);
|
||||
return *data;
|
||||
}
|
||||
|
||||
#endif
|
@@ -1,273 +0,0 @@
|
||||
/* Copyright (C) 2003 MySQL AB
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||
|
||||
#include "Code_expr.hpp"
|
||||
#include "Code_expr_conv.hpp"
|
||||
#include "Code_root.hpp"
|
||||
|
||||
// Plan_expr_conv
|
||||
|
||||
Plan_expr_conv::~Plan_expr_conv()
|
||||
{
|
||||
}
|
||||
|
||||
Plan_base*
|
||||
Plan_expr_conv::analyze(Ctx& ctx, Ctl& ctl)
|
||||
{
|
||||
m_exec = 0;
|
||||
const SqlType& t1 = sqlType();
|
||||
ctx_assert(m_expr != 0);
|
||||
m_expr->analyze(ctx, ctl);
|
||||
if (! ctx.ok())
|
||||
return 0;
|
||||
const SqlType& t2 = m_expr->sqlType();
|
||||
if (t2.type() == SqlType::Unbound) {
|
||||
return m_expr;
|
||||
}
|
||||
if (t1.equal(t2)) {
|
||||
return m_expr;
|
||||
}
|
||||
// XXX move to runtime or make table-driven
|
||||
bool ok = false;
|
||||
if (t2.type() == SqlType::Null) {
|
||||
ok = true;
|
||||
} else if (t1.type() == SqlType::Char) {
|
||||
if (t2.type() == SqlType::Char) {
|
||||
ok = true;
|
||||
} else if (t2.type() == SqlType::Varchar) {
|
||||
ok = true;
|
||||
} else if (t2.type() == SqlType::Binary) {
|
||||
ok = true;
|
||||
} else if (t2.type() == SqlType::Varbinary) {
|
||||
ok = true;
|
||||
}
|
||||
} else if (t1.type() == SqlType::Varchar) {
|
||||
if (t2.type() == SqlType::Char) {
|
||||
ok = true;
|
||||
} else if (t2.type() == SqlType::Varchar) {
|
||||
ok = true;
|
||||
} else if (t2.type() == SqlType::Binary) {
|
||||
ok = true;
|
||||
} else if (t2.type() == SqlType::Varbinary) {
|
||||
ok = true;
|
||||
}
|
||||
} else if (t1.type() == SqlType::Binary) {
|
||||
if (t2.type() == SqlType::Char) {
|
||||
ok = true;
|
||||
} else if (t2.type() == SqlType::Varchar) {
|
||||
ok = true;
|
||||
} else if (t2.type() == SqlType::Binary) {
|
||||
ok = true;
|
||||
} else if (t2.type() == SqlType::Varbinary) {
|
||||
ok = true;
|
||||
}
|
||||
} else if (t1.type() == SqlType::Varbinary) {
|
||||
if (t2.type() == SqlType::Char) {
|
||||
ok = true;
|
||||
} else if (t2.type() == SqlType::Varchar) {
|
||||
ok = true;
|
||||
} else if (t2.type() == SqlType::Binary) {
|
||||
ok = true;
|
||||
} else if (t2.type() == SqlType::Varbinary) {
|
||||
ok = true;
|
||||
}
|
||||
} else if (t1.type() == SqlType::Smallint) {
|
||||
if (t2.type() == SqlType::Smallint) {
|
||||
ok = true;
|
||||
} else if (t2.type() == SqlType::Integer) {
|
||||
ok = true;
|
||||
} else if (t2.type() == SqlType::Bigint) {
|
||||
ok = true;
|
||||
} else if (t2.type() == SqlType::Real) {
|
||||
ok = true;
|
||||
} else if (t2.type() == SqlType::Double) {
|
||||
ok = true;
|
||||
}
|
||||
} else if (t1.type() == SqlType::Integer) {
|
||||
if (t2.type() == SqlType::Smallint) {
|
||||
ok = true;
|
||||
} else if (t2.type() == SqlType::Integer) {
|
||||
ok = true;
|
||||
} else if (t2.type() == SqlType::Bigint) {
|
||||
ok = true;
|
||||
} else if (t2.type() == SqlType::Real) {
|
||||
ok = true;
|
||||
} else if (t2.type() == SqlType::Double) {
|
||||
ok = true;
|
||||
}
|
||||
} else if (t1.type() == SqlType::Bigint) {
|
||||
if (t2.type() == SqlType::Smallint) {
|
||||
ok = true;
|
||||
} else if (t2.type() == SqlType::Integer) {
|
||||
ok = true;
|
||||
} else if (t2.type() == SqlType::Bigint) {
|
||||
ok = true;
|
||||
} else if (t2.type() == SqlType::Real) {
|
||||
ok = true;
|
||||
} else if (t2.type() == SqlType::Double) {
|
||||
ok = true;
|
||||
}
|
||||
} else if (t1.type() == SqlType::Real) {
|
||||
if (t2.type() == SqlType::Smallint) {
|
||||
ok = true;
|
||||
} else if (t2.type() == SqlType::Integer) {
|
||||
ok = true;
|
||||
} else if (t2.type() == SqlType::Bigint) {
|
||||
ok = true;
|
||||
} else if (t2.type() == SqlType::Real) {
|
||||
ok = true;
|
||||
} else if (t2.type() == SqlType::Double) {
|
||||
ok = true;
|
||||
}
|
||||
} else if (t1.type() == SqlType::Double) {
|
||||
if (t2.type() == SqlType::Smallint) {
|
||||
ok = true;
|
||||
} else if (t2.type() == SqlType::Integer) {
|
||||
ok = true;
|
||||
} else if (t2.type() == SqlType::Bigint) {
|
||||
ok = true;
|
||||
} else if (t2.type() == SqlType::Real) {
|
||||
ok = true;
|
||||
} else if (t2.type() == SqlType::Double) {
|
||||
ok = true;
|
||||
}
|
||||
} else if (t1.type() == SqlType::Datetime) {
|
||||
if (t2.type() == SqlType::Datetime) {
|
||||
ok = true;
|
||||
}
|
||||
}
|
||||
if (! ok) {
|
||||
char b1[40], b2[40];
|
||||
t1.print(b1, sizeof(b1));
|
||||
t2.print(b2, sizeof(b2));
|
||||
ctx.pushStatus(Error::Gen, "cannot convert %s to %s", b2, b1);
|
||||
return 0;
|
||||
}
|
||||
// depend on same tables
|
||||
const TableSet& ts = m_expr->tableSet();
|
||||
m_tableSet.insert(ts.begin(), ts.end());
|
||||
// set alias
|
||||
m_alias = m_expr->getAlias();
|
||||
return this;
|
||||
}
|
||||
|
||||
Exec_base*
|
||||
Plan_expr_conv::codegen(Ctx& ctx, Ctl& ctl)
|
||||
{
|
||||
if (m_exec != 0)
|
||||
return m_exec;
|
||||
Exec_expr_conv* exec = new Exec_expr_conv(ctl.m_execRoot);
|
||||
ctl.m_execRoot->saveNode(exec);
|
||||
// create code for subexpression
|
||||
ctx_assert(m_expr != 0);
|
||||
Exec_expr* execExpr = static_cast<Exec_expr*>(m_expr->codegen(ctx, ctl));
|
||||
if (! ctx.ok())
|
||||
return 0;
|
||||
exec->setExpr(execExpr);
|
||||
// create the code
|
||||
SqlSpec sqlSpec(sqlType(), SqlSpec::Physical);
|
||||
Exec_expr_conv::Code& code = *new Exec_expr_conv::Code(sqlSpec);
|
||||
exec->setCode(code);
|
||||
m_exec = exec;
|
||||
return exec;
|
||||
}
|
||||
|
||||
void
|
||||
Plan_expr_conv::print(Ctx& ctx)
|
||||
{
|
||||
ctx.print(" [expr_conv ");
|
||||
char buf[100];
|
||||
m_sqlType.print(buf, sizeof(buf));
|
||||
ctx.print("%s", buf);
|
||||
Plan_base* a[] = { m_expr };
|
||||
printList(ctx, a, 1);
|
||||
ctx.print("]");
|
||||
}
|
||||
|
||||
bool
|
||||
Plan_expr_conv::isEqual(const Plan_expr* expr) const
|
||||
{
|
||||
ctx_assert(expr != 0);
|
||||
if (expr->type() != Plan_expr::TypeConv)
|
||||
return false;
|
||||
const Plan_expr_conv* expr2 = static_cast<const Plan_expr_conv*>(expr);
|
||||
if (! m_sqlType.equal(expr2->m_sqlType))
|
||||
return false;
|
||||
ctx_assert(m_expr != 0 && expr2->m_expr != 0);
|
||||
if (! m_expr->isEqual(expr2->m_expr))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
Plan_expr_conv::isGroupBy(const Plan_expr_row* row) const
|
||||
{
|
||||
if (isAnyEqual(row))
|
||||
return true;
|
||||
ctx_assert(m_expr != 0);
|
||||
if (m_expr->isGroupBy(row))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
// Code_expr_conv
|
||||
|
||||
Exec_expr_conv::Code::~Code()
|
||||
{
|
||||
}
|
||||
|
||||
Exec_expr_conv::Data::~Data()
|
||||
{
|
||||
}
|
||||
|
||||
Exec_expr_conv::~Exec_expr_conv()
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
Exec_expr_conv::alloc(Ctx& ctx, Ctl& ctl)
|
||||
{
|
||||
if (m_data != 0)
|
||||
return;
|
||||
const Code& code = getCode();
|
||||
// allocate subexpression
|
||||
ctx_assert(m_expr != 0);
|
||||
m_expr->alloc(ctx, ctl);
|
||||
if (! ctx.ok())
|
||||
return;
|
||||
SqlField sqlField(code.m_sqlSpec);
|
||||
Data& data = *new Data(sqlField);
|
||||
setData(data);
|
||||
}
|
||||
|
||||
void
|
||||
Exec_expr_conv::close(Ctx& ctx)
|
||||
{
|
||||
ctx_assert(m_expr != 0);
|
||||
m_expr->close(ctx);
|
||||
Data& data = getData();
|
||||
data.m_groupField.clear();
|
||||
}
|
||||
|
||||
void
|
||||
Exec_expr_conv::print(Ctx& ctx)
|
||||
{
|
||||
const Code& code = getCode();
|
||||
ctx.print(" [expr_conv");
|
||||
Exec_base* a[] = { m_expr };
|
||||
printList(ctx, a, sizeof(a)/sizeof(a[0]));
|
||||
ctx.print("]");
|
||||
}
|
@@ -1,141 +0,0 @@
|
||||
/* Copyright (C) 2003 MySQL AB
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||
|
||||
#ifndef ODBC_CODEGEN_Code_expr_conv_hpp
|
||||
#define ODBC_CODEGEN_Code_expr_conv_hpp
|
||||
|
||||
#include <common/common.hpp>
|
||||
#include <common/DataField.hpp>
|
||||
#include "Code_expr.hpp"
|
||||
|
||||
/**
|
||||
* @class Plan_expr_conv
|
||||
* @brief Data type conversion in PlanTree
|
||||
*
|
||||
* Inserted to convert value to another compatible type.
|
||||
*/
|
||||
class Plan_expr_conv : public Plan_expr {
|
||||
public:
|
||||
Plan_expr_conv(Plan_root* root, const SqlType& sqlType);
|
||||
virtual ~Plan_expr_conv();
|
||||
Plan_base* analyze(Ctx& ctx, Ctl& ctl);
|
||||
Exec_base* codegen(Ctx& ctx, Ctl& ctl);
|
||||
void print(Ctx& ctx);
|
||||
bool isEqual(const Plan_expr* expr) const;
|
||||
bool isGroupBy(const Plan_expr_row* row) const;
|
||||
// children
|
||||
void setExpr(Plan_expr* expr);
|
||||
protected:
|
||||
Plan_expr* m_expr;
|
||||
};
|
||||
|
||||
inline
|
||||
Plan_expr_conv::Plan_expr_conv(Plan_root* root, const SqlType& sqlType) :
|
||||
Plan_expr(root, TypeConv),
|
||||
m_expr(0)
|
||||
{
|
||||
ctx_assert(sqlType.type() != SqlType::Undef);
|
||||
m_sqlType = sqlType;
|
||||
}
|
||||
|
||||
inline void
|
||||
Plan_expr_conv::setExpr(Plan_expr* expr)
|
||||
{
|
||||
ctx_assert(expr != 0);
|
||||
m_expr = expr;
|
||||
}
|
||||
|
||||
/**
|
||||
* @class Exec_expr_conv
|
||||
* @brief Data type conversion in ExecTree
|
||||
*/
|
||||
class Exec_expr_conv : public Exec_expr {
|
||||
public:
|
||||
class Code : public Exec_expr::Code {
|
||||
public:
|
||||
Code(const SqlSpec& spec);
|
||||
virtual ~Code();
|
||||
protected:
|
||||
friend class Exec_expr_conv;
|
||||
const SqlSpec m_sqlSpec;
|
||||
};
|
||||
class Data : public Exec_expr::Data {
|
||||
public:
|
||||
Data(const SqlField& sqlField);
|
||||
virtual ~Data();
|
||||
protected:
|
||||
friend class Exec_expr_conv;
|
||||
SqlField m_sqlField;
|
||||
};
|
||||
Exec_expr_conv(Exec_root* root);
|
||||
virtual ~Exec_expr_conv();
|
||||
void alloc(Ctx& ctx, Ctl& ctl);
|
||||
void evaluate(Ctx& ctx, Ctl& ctl);
|
||||
void close(Ctx& ctx);
|
||||
void print(Ctx& ctx);
|
||||
// children
|
||||
const Code& getCode() const;
|
||||
Data& getData() const;
|
||||
void setExpr(Exec_expr* expr);
|
||||
protected:
|
||||
Exec_expr* m_expr;
|
||||
};
|
||||
|
||||
inline
|
||||
Exec_expr_conv::Code::Code(const SqlSpec& sqlSpec) :
|
||||
Exec_expr::Code(m_sqlSpec),
|
||||
m_sqlSpec(sqlSpec)
|
||||
{
|
||||
}
|
||||
|
||||
inline
|
||||
Exec_expr_conv::Data::Data(const SqlField& sqlField) :
|
||||
Exec_expr::Data(m_sqlField),
|
||||
m_sqlField(sqlField)
|
||||
{
|
||||
}
|
||||
|
||||
inline
|
||||
Exec_expr_conv::Exec_expr_conv(Exec_root* root) :
|
||||
Exec_expr(root),
|
||||
m_expr(0)
|
||||
{
|
||||
}
|
||||
|
||||
// children
|
||||
|
||||
inline const Exec_expr_conv::Code&
|
||||
Exec_expr_conv::getCode() const
|
||||
{
|
||||
const Code* code = static_cast<const Code*>(m_code);
|
||||
return *code;
|
||||
}
|
||||
|
||||
inline Exec_expr_conv::Data&
|
||||
Exec_expr_conv::getData() const
|
||||
{
|
||||
Data* data = static_cast<Data*>(m_data);
|
||||
return *data;
|
||||
}
|
||||
|
||||
inline void
|
||||
Exec_expr_conv::setExpr(Exec_expr* expr)
|
||||
{
|
||||
ctx_assert(m_expr == 0 && expr != 0);
|
||||
m_expr = expr;
|
||||
}
|
||||
|
||||
#endif
|
@@ -1,401 +0,0 @@
|
||||
/* Copyright (C) 2003 MySQL AB
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||
|
||||
#include "Code_expr.hpp"
|
||||
#include "Code_expr_func.hpp"
|
||||
#include "Code_expr_conv.hpp"
|
||||
#include "Code_root.hpp"
|
||||
#include "PortDefs.h"
|
||||
|
||||
|
||||
// Expr_func
|
||||
|
||||
static const struct { const char* alias; const char* name; }
|
||||
expr_func_alias[] = {
|
||||
{ "SUBSTRING", "SUBSTR" },
|
||||
{ 0, 0 }
|
||||
};
|
||||
|
||||
static const Expr_func
|
||||
expr_func[] = {
|
||||
Expr_func(Expr_func::Substr, "SUBSTR", false ),
|
||||
Expr_func(Expr_func::Left, "LEFT", false ),
|
||||
Expr_func(Expr_func::Right, "RIGHT", false ),
|
||||
Expr_func(Expr_func::Count, "COUNT", true ),
|
||||
Expr_func(Expr_func::Max, "MAX", true ),
|
||||
Expr_func(Expr_func::Min, "MIN", true ),
|
||||
Expr_func(Expr_func::Sum, "SUM", true ),
|
||||
Expr_func(Expr_func::Avg, "AVG", true ),
|
||||
Expr_func(Expr_func::Rownum, "ROWNUM", false ),
|
||||
Expr_func(Expr_func::Sysdate, "SYSDATE", false ),
|
||||
Expr_func(Expr_func::Undef, 0, false )
|
||||
};
|
||||
|
||||
const Expr_func&
|
||||
Expr_func::find(const char* name)
|
||||
{
|
||||
for (unsigned i = 0; expr_func_alias[i].alias != 0; i++) {
|
||||
if (strcasecmp(expr_func_alias[i].alias, name) == 0) {
|
||||
name = expr_func_alias[i].name;
|
||||
break;
|
||||
}
|
||||
}
|
||||
const Expr_func* p;
|
||||
for (p = expr_func; p->m_name != 0; p++) {
|
||||
if (strcasecmp(p->m_name, name) == 0)
|
||||
break;
|
||||
}
|
||||
return *p;
|
||||
}
|
||||
|
||||
// Plan_expr_func
|
||||
|
||||
Plan_expr_func::~Plan_expr_func()
|
||||
{
|
||||
delete[] m_conv;
|
||||
m_conv = 0;
|
||||
}
|
||||
|
||||
Plan_base*
|
||||
Plan_expr_func::analyze(Ctx& ctx, Ctl& ctl)
|
||||
{
|
||||
m_exec = 0;
|
||||
ctx_assert(m_narg == 0 || m_args != 0);
|
||||
// aggregate check
|
||||
if (m_func.m_aggr) {
|
||||
if (! ctl.m_aggrok) {
|
||||
ctx.pushStatus(Error::Gen, "%s: invalid use of aggregate function", m_func.m_name);
|
||||
return 0;
|
||||
}
|
||||
if (ctl.m_aggrin) {
|
||||
// XXX actually possible with group-by but too hard
|
||||
ctx.pushStatus(Error::Gen, "%s: nested aggregate function", m_func.m_name);
|
||||
return 0;
|
||||
}
|
||||
ctl.m_aggrin = true;
|
||||
m_isAggr = true;
|
||||
m_isBound = true;
|
||||
}
|
||||
// analyze argument expressions
|
||||
if (m_func.m_code != Expr_func::Rownum)
|
||||
m_isBound = true;
|
||||
for (unsigned i = 1; i <= m_narg; i++) {
|
||||
Plan_expr* expr = m_args->getExpr(i);
|
||||
expr = static_cast<Plan_expr*>(expr->analyze(ctx, ctl));
|
||||
if (! ctx.ok())
|
||||
return 0;
|
||||
ctx_assert(expr != 0);
|
||||
if (expr->m_isAggr)
|
||||
m_isAggr = true;
|
||||
if (! m_func.m_aggr && ! expr->m_isBound)
|
||||
m_isBound = false;
|
||||
}
|
||||
if (m_func.m_aggr)
|
||||
ctl.m_aggrin = false;
|
||||
// find result type and conversion types
|
||||
SqlType res;
|
||||
const Expr_func::Code fc = m_func.m_code;
|
||||
const char* const invalidArgCount = "%s: argument count %u is invalid";
|
||||
const char* const invalidArgType = "%s: argument %u has invalid type";
|
||||
if (fc == Expr_func::Substr || fc == Expr_func::Left || fc == Expr_func::Right) {
|
||||
if ((m_narg != (unsigned)2) && (m_narg != (unsigned)(fc == Expr_func::Substr ? 3 : 2))) {
|
||||
ctx.pushStatus(Error::Gen, invalidArgCount, m_func.m_name, m_narg);
|
||||
return 0;
|
||||
}
|
||||
const SqlType& t1 = m_args->getExpr(1)->sqlType();
|
||||
switch (t1.type()) {
|
||||
case SqlType::Char:
|
||||
{
|
||||
// XXX convert to varchar for now to get length right
|
||||
SqlType tx(SqlType::Varchar, t1.length());
|
||||
res = m_conv[1] = tx;
|
||||
}
|
||||
break;
|
||||
case SqlType::Varchar:
|
||||
case SqlType::Unbound:
|
||||
res = m_conv[1] = t1;
|
||||
break;
|
||||
default:
|
||||
ctx.pushStatus(Error::Gen, invalidArgType, m_func.m_name, 1);
|
||||
return 0;
|
||||
}
|
||||
for (unsigned i = 2; i <= m_narg; i++) {
|
||||
const SqlType& t2 = m_args->getExpr(i)->sqlType();
|
||||
switch (t2.type()) {
|
||||
case SqlType::Smallint:
|
||||
case SqlType::Integer:
|
||||
case SqlType::Bigint:
|
||||
case SqlType::Unbound:
|
||||
m_conv[i] = t2;
|
||||
break;
|
||||
default:
|
||||
ctx.pushStatus(Error::Gen, invalidArgType, m_func.m_name, i);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
} else if (fc == Expr_func::Count) {
|
||||
ctx_assert(m_args != 0);
|
||||
if (m_args->getAsterisk()) {
|
||||
ctx_assert(m_narg == 0);
|
||||
} else {
|
||||
if (m_narg != 1) {
|
||||
ctx.pushStatus(Error::Gen, invalidArgCount, m_func.m_name, m_narg);
|
||||
return 0;
|
||||
}
|
||||
m_conv[1] = m_args->getExpr(1)->sqlType();
|
||||
}
|
||||
res.setType(ctx, SqlType::Bigint);
|
||||
} else if (fc == Expr_func::Min || fc == Expr_func::Max) {
|
||||
if (m_narg != 1) {
|
||||
ctx.pushStatus(Error::Gen, invalidArgCount, m_func.m_name, m_narg);
|
||||
return 0;
|
||||
}
|
||||
const SqlType& t1 = m_args->getExpr(1)->sqlType();
|
||||
res = m_conv[1] = t1;
|
||||
} else if (fc == Expr_func::Sum) {
|
||||
if (m_narg != 1) {
|
||||
ctx.pushStatus(Error::Gen, invalidArgCount, m_func.m_name, m_narg);
|
||||
return 0;
|
||||
}
|
||||
const SqlType& t1 = m_args->getExpr(1)->sqlType();
|
||||
switch (t1.type()) {
|
||||
case SqlType::Smallint:
|
||||
case SqlType::Integer:
|
||||
case SqlType::Bigint:
|
||||
res.setType(ctx, SqlType::Bigint);
|
||||
m_conv[1] = res;
|
||||
break;
|
||||
case SqlType::Real:
|
||||
case SqlType::Double:
|
||||
res.setType(ctx, SqlType::Double);
|
||||
m_conv[1] = res;
|
||||
break;
|
||||
case SqlType::Unbound:
|
||||
res = m_conv[1] = t1;
|
||||
break;
|
||||
default:
|
||||
ctx.pushStatus(Error::Gen, invalidArgType, m_func.m_name, 1);
|
||||
return 0;
|
||||
}
|
||||
} else if (fc == Expr_func::Avg) {
|
||||
if (m_narg != 1) {
|
||||
ctx.pushStatus(Error::Gen, invalidArgCount, m_func.m_name, m_narg);
|
||||
return 0;
|
||||
}
|
||||
const SqlType& t1 = m_args->getExpr(1)->sqlType();
|
||||
switch (t1.type()) {
|
||||
case SqlType::Smallint:
|
||||
case SqlType::Integer:
|
||||
case SqlType::Bigint:
|
||||
case SqlType::Real:
|
||||
case SqlType::Double:
|
||||
res.setType(ctx, SqlType::Double);
|
||||
m_conv[1] = res;
|
||||
break;
|
||||
case SqlType::Unbound:
|
||||
res = m_conv[1] = t1;
|
||||
break;
|
||||
default:
|
||||
ctx.pushStatus(Error::Gen, invalidArgType, m_func.m_name, 1);
|
||||
return 0;
|
||||
}
|
||||
} else if (fc == Expr_func::Rownum) {
|
||||
ctx_assert(m_narg == 0 && m_args == 0);
|
||||
res.setType(ctx, SqlType::Bigint);
|
||||
} else if (fc == Expr_func::Sysdate) {
|
||||
ctx_assert(m_narg == 0 && m_args == 0);
|
||||
res.setType(ctx, SqlType::Datetime);
|
||||
} else {
|
||||
ctx_assert(false);
|
||||
}
|
||||
// insert required conversions
|
||||
for (unsigned i = 1; i <= m_narg; i++) {
|
||||
if (m_conv[i].type() == SqlType::Unbound) {
|
||||
// parameter type not yet bound
|
||||
continue;
|
||||
}
|
||||
Plan_expr_conv* exprConv = new Plan_expr_conv(m_root, m_conv[i]);
|
||||
m_root->saveNode(exprConv);
|
||||
exprConv->setExpr(m_args->getExpr(i));
|
||||
Plan_expr* expr = static_cast<Plan_expr*>(exprConv->analyze(ctx, ctl));
|
||||
if (! ctx.ok())
|
||||
return 0;
|
||||
m_args->setExpr(i, expr);
|
||||
}
|
||||
// set result type
|
||||
m_sqlType = res;
|
||||
// set table dependencies
|
||||
for (unsigned i = 1; i <= m_narg; i++) {
|
||||
const TableSet& ts = m_args->getExpr(i)->tableSet();
|
||||
m_tableSet.insert(ts.begin(), ts.end());
|
||||
}
|
||||
// set alias name
|
||||
m_alias.assign(m_func.m_name);
|
||||
if (m_narg == 0) {
|
||||
if (fc == Expr_func::Count)
|
||||
m_alias.append("(*)");
|
||||
} else {
|
||||
m_alias.append("(");
|
||||
for (unsigned i = 1; i <= m_narg; i++) {
|
||||
if (i > 1)
|
||||
m_alias.append(",");
|
||||
m_alias.append(m_args->getExpr(i)->getAlias());
|
||||
}
|
||||
m_alias.append(")");
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
Exec_base*
|
||||
Plan_expr_func::codegen(Ctx& ctx, Ctl& ctl)
|
||||
{
|
||||
if (m_exec != 0)
|
||||
return m_exec;
|
||||
Exec_expr_func* exec = new Exec_expr_func(ctl.m_execRoot);
|
||||
ctl.m_execRoot->saveNode(exec);
|
||||
SqlSpec sqlSpec(sqlType(), SqlSpec::Physical);
|
||||
Exec_expr_func::Code& code = *new Exec_expr_func::Code(m_func, sqlSpec);
|
||||
exec->setCode(code);
|
||||
code.m_narg = m_narg;
|
||||
code.m_args = new Exec_expr* [1 + m_narg];
|
||||
for (unsigned i = 0; i <= m_narg; i++)
|
||||
code.m_args[i] = 0;
|
||||
// create code for arguments
|
||||
for (unsigned i = 1; i <= m_narg; i++) {
|
||||
Plan_expr* expr = m_args->getExpr(i);
|
||||
ctx_assert(expr != 0);
|
||||
Exec_expr* execExpr = static_cast<Exec_expr*>(expr->codegen(ctx, ctl));
|
||||
if (! ctx.ok())
|
||||
return 0;
|
||||
ctx_assert(execExpr != 0);
|
||||
code.m_args[i] = execExpr;
|
||||
}
|
||||
m_exec = exec;
|
||||
return exec;
|
||||
}
|
||||
|
||||
void
|
||||
Plan_expr_func::print(Ctx& ctx)
|
||||
{
|
||||
ctx.print(" [%s", m_func.m_name);
|
||||
Plan_base* a[] = { m_args };
|
||||
printList(ctx, a, sizeof(a)/sizeof(a[1]));
|
||||
ctx.print("]");
|
||||
}
|
||||
|
||||
bool
|
||||
Plan_expr_func::isEqual(const Plan_expr* expr) const
|
||||
{
|
||||
ctx_assert(expr != 0);
|
||||
if (expr->type() != Plan_expr::TypeFunc)
|
||||
return false;
|
||||
const Plan_expr_func* expr2 = static_cast<const Plan_expr_func*>(expr);
|
||||
if (m_func.m_code != expr2->m_func.m_code)
|
||||
return false;
|
||||
if (m_narg != expr2->m_narg)
|
||||
return false;
|
||||
ctx_assert(m_args != 0 && expr2->m_args != 0);
|
||||
for (unsigned i = 1; i <= m_narg; i++) {
|
||||
if (! m_args->getExpr(i)->isEqual(expr2->m_args->getExpr(i)))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
Plan_expr_func::isGroupBy(const Plan_expr_row* row) const
|
||||
{
|
||||
if (m_func.m_aggr)
|
||||
return true;
|
||||
switch (m_func.m_code) {
|
||||
case Expr_func::Substr:
|
||||
case Expr_func::Left:
|
||||
case Expr_func::Right:
|
||||
ctx_assert(m_narg >= 1);
|
||||
if (m_args->getExpr(1)->isGroupBy(row))
|
||||
return true;
|
||||
break;
|
||||
case Expr_func::Sysdate:
|
||||
return true;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if (isAnyEqual(row))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
// Exec_expr_func
|
||||
|
||||
Exec_expr_func::Code::~Code()
|
||||
{
|
||||
delete[] m_args;
|
||||
m_args = 0;
|
||||
}
|
||||
|
||||
Exec_expr_func::Data::~Data()
|
||||
{
|
||||
}
|
||||
|
||||
Exec_expr_func::~Exec_expr_func()
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
Exec_expr_func::alloc(Ctx& ctx, Ctl& ctl)
|
||||
{
|
||||
if (m_data != 0)
|
||||
return;
|
||||
const Code& code = getCode();
|
||||
// allocate arguments
|
||||
for (unsigned i = 1; i <= code.m_narg; i++) {
|
||||
ctx_assert(code.m_args != 0 && code.m_args[i] != 0);
|
||||
code.m_args[i]->alloc(ctx, ctl);
|
||||
if (! ctx.ok())
|
||||
return;
|
||||
}
|
||||
SqlField sqlField(code.m_sqlSpec);
|
||||
Data& data = *new Data(sqlField);
|
||||
setData(data);
|
||||
ctx_assert(ctl.m_groupIndex == 0);
|
||||
init(ctx, ctl);
|
||||
}
|
||||
|
||||
void
|
||||
Exec_expr_func::close(Ctx& ctx)
|
||||
{
|
||||
const Code& code = getCode();
|
||||
Data& data = getData();
|
||||
for (unsigned i = 1; i <= code.m_narg; i++) {
|
||||
ctx_assert(code.m_args != 0 && code.m_args[i] != 0);
|
||||
code.m_args[i]->close(ctx);
|
||||
}
|
||||
data.m_groupField.clear();
|
||||
Ctl ctl(0);
|
||||
init(ctx, ctl);
|
||||
}
|
||||
|
||||
void
|
||||
Exec_expr_func::print(Ctx& ctx)
|
||||
{
|
||||
const Code& code = getCode();
|
||||
ctx.print(" [%s", code.m_func.m_name);
|
||||
for (unsigned i = 1; i <= code.m_narg; i++) {
|
||||
Exec_base* a[] = { code.m_args[i] };
|
||||
printList(ctx, a, sizeof(a)/sizeof(a[0]));
|
||||
}
|
||||
ctx.print("]");
|
||||
}
|
@@ -1,193 +0,0 @@
|
||||
/* Copyright (C) 2003 MySQL AB
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||
|
||||
#ifndef ODBC_CODEGEN_Code_expr_func_hpp
|
||||
#define ODBC_CODEGEN_Code_expr_func_hpp
|
||||
|
||||
#include <common/common.hpp>
|
||||
#include <common/DataField.hpp>
|
||||
#include "Code_expr.hpp"
|
||||
#include "Code_expr_row.hpp"
|
||||
|
||||
/**
|
||||
* @class Expr_func
|
||||
* @brief Specifies a function
|
||||
*/
|
||||
struct Expr_func {
|
||||
enum Code {
|
||||
Undef = 0,
|
||||
Substr,
|
||||
Left,
|
||||
Right,
|
||||
Count,
|
||||
Max,
|
||||
Min,
|
||||
Sum,
|
||||
Avg,
|
||||
Rownum,
|
||||
Sysdate
|
||||
};
|
||||
Expr_func(Code code, const char* name, bool aggr);
|
||||
Code m_code;
|
||||
const char* m_name;
|
||||
bool m_aggr;
|
||||
static const Expr_func& find(const char* name);
|
||||
};
|
||||
|
||||
inline
|
||||
Expr_func::Expr_func(Code code, const char* name, bool aggr) :
|
||||
m_code(code),
|
||||
m_name(name),
|
||||
m_aggr(aggr)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @class Plan_expr_func
|
||||
* @brief Function node in an expression in PlanTree
|
||||
*/
|
||||
class Plan_expr_func : public Plan_expr {
|
||||
public:
|
||||
Plan_expr_func(Plan_root* root, const Expr_func& func);
|
||||
virtual ~Plan_expr_func();
|
||||
Plan_base* analyze(Ctx& ctx, Ctl& ctl);
|
||||
Exec_base* codegen(Ctx& ctx, Ctl& ctl);
|
||||
void print(Ctx& ctx);
|
||||
bool isEqual(const Plan_expr* expr) const;
|
||||
bool isGroupBy(const Plan_expr_row* row) const;
|
||||
// children
|
||||
void setArgs(Plan_expr_row* args);
|
||||
protected:
|
||||
const Expr_func& m_func;
|
||||
Plan_expr_row* m_args;
|
||||
unsigned m_narg;
|
||||
SqlType* m_conv; // temp work area
|
||||
};
|
||||
|
||||
inline
|
||||
Plan_expr_func::Plan_expr_func(Plan_root* root, const Expr_func& func) :
|
||||
Plan_expr(root, TypeFunc),
|
||||
m_func(func),
|
||||
m_args(0),
|
||||
m_narg(0),
|
||||
m_conv(0)
|
||||
{
|
||||
}
|
||||
|
||||
inline void
|
||||
Plan_expr_func::setArgs(Plan_expr_row* args)
|
||||
{
|
||||
if (args == 0) {
|
||||
m_args = 0;
|
||||
m_narg = 0;
|
||||
} else {
|
||||
m_args = args;
|
||||
m_narg = m_args->getSize();
|
||||
delete[] m_conv;
|
||||
m_conv = new SqlType[1 + m_narg];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @class Exec_expr_func
|
||||
* @brief Function node in an expression in ExecTree
|
||||
*/
|
||||
class Exec_expr_func : public Exec_expr {
|
||||
public:
|
||||
class Code : public Exec_expr::Code {
|
||||
public:
|
||||
Code(const Expr_func& func, const SqlSpec& spec);
|
||||
virtual ~Code();
|
||||
protected:
|
||||
friend class Plan_expr_func;
|
||||
friend class Exec_expr_func;
|
||||
const Expr_func& m_func;
|
||||
const SqlSpec m_sqlSpec;
|
||||
unsigned m_narg;
|
||||
Exec_expr** m_args; // XXX pointers for now
|
||||
};
|
||||
class Data : public Exec_expr::Data {
|
||||
public:
|
||||
Data(const SqlField& sqlField);
|
||||
virtual ~Data();
|
||||
protected:
|
||||
friend class Exec_expr_func;
|
||||
SqlField m_sqlField;
|
||||
struct Acc { // accumulators etc
|
||||
SqlBigint m_count; // current row count
|
||||
union {
|
||||
SqlBigint m_bigint;
|
||||
SqlDouble m_double;
|
||||
SqlDatetime m_sysdate;
|
||||
};
|
||||
};
|
||||
// group-by extra accumulators (default in entry 0)
|
||||
typedef std::vector<Acc> GroupAcc;
|
||||
GroupAcc m_groupAcc;
|
||||
};
|
||||
Exec_expr_func(Exec_root* root);
|
||||
virtual ~Exec_expr_func();
|
||||
void alloc(Ctx& ctx, Ctl& ctl);
|
||||
void evaluate(Ctx& ctx, Ctl& ctl);
|
||||
void close(Ctx& ctx);
|
||||
void print(Ctx& ctx);
|
||||
// children
|
||||
const Code& getCode() const;
|
||||
Data& getData() const;
|
||||
protected:
|
||||
void init(Ctx &ctx, Ctl& ctl); // initialize values
|
||||
};
|
||||
|
||||
inline
|
||||
Exec_expr_func::Code::Code(const Expr_func& func, const SqlSpec& sqlSpec) :
|
||||
Exec_expr::Code(m_sqlSpec),
|
||||
m_func(func),
|
||||
m_sqlSpec(sqlSpec),
|
||||
m_args(0)
|
||||
{
|
||||
}
|
||||
|
||||
inline
|
||||
Exec_expr_func::Data::Data(const SqlField& sqlField) :
|
||||
Exec_expr::Data(m_sqlField),
|
||||
m_sqlField(sqlField),
|
||||
m_groupAcc(1)
|
||||
{
|
||||
}
|
||||
|
||||
inline
|
||||
Exec_expr_func::Exec_expr_func(Exec_root* root) :
|
||||
Exec_expr(root)
|
||||
{
|
||||
}
|
||||
|
||||
// children
|
||||
|
||||
inline const Exec_expr_func::Code&
|
||||
Exec_expr_func::getCode() const
|
||||
{
|
||||
const Code* code = static_cast<const Code*>(m_code);
|
||||
return *code;
|
||||
}
|
||||
|
||||
inline Exec_expr_func::Data&
|
||||
Exec_expr_func::getData() const
|
||||
{
|
||||
Data* data = static_cast<Data*>(m_data);
|
||||
return *data;
|
||||
}
|
||||
|
||||
#endif
|
@@ -1,424 +0,0 @@
|
||||
/* Copyright (C) 2003 MySQL AB
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||
|
||||
#include "Code_expr.hpp"
|
||||
#include "Code_expr_op.hpp"
|
||||
#include "Code_expr_conv.hpp"
|
||||
#include "Code_root.hpp"
|
||||
|
||||
// Expr_op
|
||||
|
||||
const char*
|
||||
Expr_op::name() const
|
||||
{
|
||||
switch (m_opcode) {
|
||||
case Add:
|
||||
return "+";
|
||||
case Subtract:
|
||||
return "-";
|
||||
case Multiply:
|
||||
return "*";
|
||||
case Divide:
|
||||
return "/";
|
||||
case Plus:
|
||||
return "+";
|
||||
case Minus:
|
||||
return "-";
|
||||
}
|
||||
ctx_assert(false);
|
||||
return "";
|
||||
}
|
||||
|
||||
unsigned
|
||||
Expr_op::arity() const
|
||||
{
|
||||
switch (m_opcode) {
|
||||
case Add:
|
||||
case Subtract:
|
||||
case Multiply:
|
||||
case Divide:
|
||||
return 2;
|
||||
case Plus:
|
||||
case Minus:
|
||||
return 1;
|
||||
}
|
||||
ctx_assert(false);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Plan_expr_op
|
||||
|
||||
Plan_expr_op::~Plan_expr_op()
|
||||
{
|
||||
}
|
||||
|
||||
Plan_base*
|
||||
Plan_expr_op::analyze(Ctx& ctx, Ctl& ctl)
|
||||
{
|
||||
m_exec = 0;
|
||||
unsigned arity = m_op.arity();
|
||||
// analyze operands
|
||||
m_isAggr = false;
|
||||
m_isBound = true;
|
||||
for (unsigned i = 1; i <= arity; i++) {
|
||||
ctx_assert(m_expr[i] != 0);
|
||||
m_expr[i]->analyze(ctx, ctl);
|
||||
if (! ctx.ok())
|
||||
return 0;
|
||||
if (m_expr[i]->m_isAggr)
|
||||
m_isAggr = true;
|
||||
if (! m_expr[i]->m_isBound)
|
||||
m_isBound = false;
|
||||
}
|
||||
// find result type and conversion types (currently same)
|
||||
SqlType res;
|
||||
SqlType con[1 + 2];
|
||||
if (arity == 1) {
|
||||
const SqlType& t1 = m_expr[1]->sqlType();
|
||||
switch (t1.type()) {
|
||||
case SqlType::Char:
|
||||
case SqlType::Varchar:
|
||||
break;
|
||||
case SqlType::Smallint:
|
||||
case SqlType::Integer:
|
||||
case SqlType::Bigint:
|
||||
res.setType(ctx, SqlType::Bigint);
|
||||
con[1] = res;
|
||||
break;
|
||||
case SqlType::Real:
|
||||
case SqlType::Double:
|
||||
res.setType(ctx, SqlType::Double);
|
||||
con[1] = res;
|
||||
break;
|
||||
case SqlType::Null:
|
||||
res.setType(ctx, SqlType::Null);
|
||||
con[1] = res;
|
||||
break;
|
||||
case SqlType::Unbound:
|
||||
res.setType(ctx, SqlType::Unbound);
|
||||
con[1] = res;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if (con[1].type() == SqlType::Undef) {
|
||||
char b1[40];
|
||||
t1.print(b1, sizeof(b1));
|
||||
ctx.pushStatus(Error::Gen, "type mismatch in operation: %s %s", m_op.name(), b1);
|
||||
return 0;
|
||||
}
|
||||
} else if (arity == 2) {
|
||||
const SqlType& t1 = m_expr[1]->sqlType();
|
||||
const SqlType& t2 = m_expr[2]->sqlType();
|
||||
switch (t1.type()) {
|
||||
case SqlType::Char: // handle char types as in oracle
|
||||
switch (t2.type()) {
|
||||
case SqlType::Char:
|
||||
res.setType(ctx, SqlType::Char, t1.length() + t2.length());
|
||||
con[1] = t1;
|
||||
con[2] = t2;
|
||||
break;
|
||||
case SqlType::Varchar:
|
||||
res.setType(ctx, SqlType::Varchar, t1.length() + t2.length());
|
||||
con[1] = t1;
|
||||
con[2] = t2;
|
||||
break;
|
||||
case SqlType::Null:
|
||||
res.setType(ctx, SqlType::Varchar, t1.length());
|
||||
con[1] = t1;
|
||||
con[2] = t2;
|
||||
break;
|
||||
case SqlType::Unbound:
|
||||
res.setType(ctx, SqlType::Unbound);
|
||||
con[1] = con[2] = res;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case SqlType::Varchar:
|
||||
switch (t2.type()) {
|
||||
case SqlType::Char:
|
||||
res.setType(ctx, SqlType::Varchar, t1.length() + t2.length());
|
||||
con[1] = t1;
|
||||
con[2] = t2;
|
||||
break;
|
||||
case SqlType::Varchar:
|
||||
res.setType(ctx, SqlType::Varchar, t1.length() + t2.length());
|
||||
con[1] = t1;
|
||||
con[2] = t2;
|
||||
break;
|
||||
case SqlType::Null:
|
||||
res.setType(ctx, SqlType::Varchar, t1.length());
|
||||
con[1] = t1;
|
||||
con[2] = t2;
|
||||
break;
|
||||
case SqlType::Unbound:
|
||||
res.setType(ctx, SqlType::Unbound);
|
||||
con[1] = con[2] = res;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case SqlType::Smallint:
|
||||
case SqlType::Integer:
|
||||
case SqlType::Bigint:
|
||||
switch (t2.type()) {
|
||||
case SqlType::Smallint:
|
||||
case SqlType::Integer:
|
||||
case SqlType::Bigint:
|
||||
res.setType(ctx, SqlType::Bigint);
|
||||
con[1] = con[2] = res;
|
||||
if (t1.unSigned() || t2.unSigned()) {
|
||||
con[1].unSigned(true);
|
||||
con[2].unSigned(true);
|
||||
}
|
||||
break;
|
||||
case SqlType::Real:
|
||||
case SqlType::Double:
|
||||
res.setType(ctx, SqlType::Double);
|
||||
con[1] = con[2] = res;
|
||||
break;
|
||||
case SqlType::Null:
|
||||
res.setType(ctx, SqlType::Null);
|
||||
con[1] = con[2] = res;
|
||||
break;
|
||||
case SqlType::Unbound:
|
||||
res.setType(ctx, SqlType::Unbound);
|
||||
con[1] = con[2] = res;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case SqlType::Real:
|
||||
case SqlType::Double:
|
||||
switch (t2.type()) {
|
||||
case SqlType::Smallint:
|
||||
case SqlType::Integer:
|
||||
case SqlType::Bigint:
|
||||
case SqlType::Real:
|
||||
case SqlType::Double:
|
||||
res.setType(ctx, SqlType::Double);
|
||||
con[1] = con[2] = res;
|
||||
break;
|
||||
case SqlType::Null:
|
||||
res.setType(ctx, SqlType::Null);
|
||||
con[1] = con[2] = res;
|
||||
break;
|
||||
case SqlType::Unbound:
|
||||
res.setType(ctx, SqlType::Unbound);
|
||||
con[1] = con[2] = res;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case SqlType::Null:
|
||||
switch (t2.type()) {
|
||||
case SqlType::Char:
|
||||
case SqlType::Varchar:
|
||||
res.setType(ctx, SqlType::Varchar, t2.length());
|
||||
con[1] = con[2] = res;
|
||||
break;
|
||||
case SqlType::Unbound:
|
||||
res.setType(ctx, SqlType::Unbound);
|
||||
con[1] = con[2] = res;
|
||||
break;
|
||||
default:
|
||||
res.setType(ctx, SqlType::Null);
|
||||
con[1] = con[2] = res;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case SqlType::Unbound:
|
||||
res.setType(ctx, SqlType::Unbound);
|
||||
con[1] = con[2] = res;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if (con[1].type() == SqlType::Undef || con[2].type() == SqlType::Undef) {
|
||||
char b1[40], b2[40];
|
||||
t1.print(b1, sizeof(b1));
|
||||
t2.print(b2, sizeof(b2));
|
||||
ctx.pushStatus(Error::Gen, "type mismatch in operation: %s %s %s", b1, m_op.name(), b2);
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
ctx_assert(false);
|
||||
return 0;
|
||||
}
|
||||
if (! ctx.ok())
|
||||
return 0;
|
||||
// insert required conversions
|
||||
for (unsigned i = 1; i <= arity; i++) {
|
||||
if (con[i].type() == SqlType::Undef) {
|
||||
ctx.pushStatus(Error::Gen, "mismatched types in operation");
|
||||
return 0;
|
||||
}
|
||||
if (con[i].type() == SqlType::Unbound) {
|
||||
// parameter type not yet bound
|
||||
continue;
|
||||
}
|
||||
Plan_expr_conv* exprConv = new Plan_expr_conv(m_root, con[i]);
|
||||
m_root->saveNode(exprConv);
|
||||
exprConv->setExpr(m_expr[i]);
|
||||
m_expr[i] = static_cast<Plan_expr*>(exprConv->analyze(ctx, ctl));
|
||||
if (! ctx.ok())
|
||||
return 0;
|
||||
ctx_assert(m_expr[i] != 0);
|
||||
}
|
||||
// set result type
|
||||
m_sqlType = res;
|
||||
// table dependencies are union from operands
|
||||
for (unsigned i = 1; i <= arity; i++) {
|
||||
const TableSet& ts = m_expr[i]->tableSet();
|
||||
m_tableSet.insert(ts.begin(), ts.end());
|
||||
}
|
||||
// set alias name XXX misses operator precedence
|
||||
if (arity == 1) {
|
||||
m_alias.assign(m_op.name());
|
||||
m_alias.append(m_expr[1]->m_alias);
|
||||
} else if (arity == 2) {
|
||||
m_alias.assign(m_expr[1]->m_alias);
|
||||
m_alias.append(m_op.name());
|
||||
m_alias.append(m_expr[2]->m_alias);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
Exec_base*
|
||||
Plan_expr_op::codegen(Ctx& ctx, Ctl& ctl)
|
||||
{
|
||||
if (m_exec != 0)
|
||||
return m_exec;
|
||||
unsigned arity = m_op.arity();
|
||||
Exec_expr_op* exec = new Exec_expr_op(ctl.m_execRoot);
|
||||
ctl.m_execRoot->saveNode(exec);
|
||||
// create code for operands
|
||||
for (unsigned i = 1; i <= arity; i++) {
|
||||
ctx_assert(m_expr[i] != 0);
|
||||
Exec_expr* execExpr = static_cast<Exec_expr*>(m_expr[i]->codegen(ctx, ctl));
|
||||
if (! ctx.ok())
|
||||
return 0;
|
||||
ctx_assert(execExpr != 0);
|
||||
exec->setExpr(i, execExpr);
|
||||
}
|
||||
// create the code
|
||||
SqlSpec sqlSpec(sqlType(), SqlSpec::Physical);
|
||||
Exec_expr_op::Code& code = *new Exec_expr_op::Code(m_op, sqlSpec);
|
||||
exec->setCode(code);
|
||||
m_exec = exec;
|
||||
return exec;
|
||||
}
|
||||
|
||||
void
|
||||
Plan_expr_op::print(Ctx& ctx)
|
||||
{
|
||||
ctx.print(" [%s", m_op.name());
|
||||
Plan_base* a[] = { m_expr[1], m_expr[2] };
|
||||
printList(ctx, a, m_op.arity());
|
||||
ctx.print("]");
|
||||
}
|
||||
|
||||
bool
|
||||
Plan_expr_op::isEqual(const Plan_expr* expr) const
|
||||
{
|
||||
ctx_assert(expr != 0);
|
||||
if (expr->type() != Plan_expr::TypeOp)
|
||||
return false;
|
||||
const Plan_expr_op* expr2 = static_cast<const Plan_expr_op*>(expr);
|
||||
if (m_op.m_opcode != expr2->m_op.m_opcode)
|
||||
return false;
|
||||
const unsigned arity = m_op.arity();
|
||||
for (unsigned i = 1; i <= arity; i++) {
|
||||
ctx_assert(m_expr[i] != 0);
|
||||
if (! m_expr[i]->isEqual(expr2->m_expr[i]))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
Plan_expr_op::isGroupBy(const Plan_expr_row* row) const
|
||||
{
|
||||
if (isAnyEqual(row))
|
||||
return true;
|
||||
const unsigned arity = m_op.arity();
|
||||
for (unsigned i = 1; i <= arity; i++) {
|
||||
ctx_assert(m_expr[i] != 0);
|
||||
if (! m_expr[i]->isGroupBy(row))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// Code_expr_op
|
||||
|
||||
Exec_expr_op::Code::~Code()
|
||||
{
|
||||
}
|
||||
|
||||
Exec_expr_op::Data::~Data()
|
||||
{
|
||||
}
|
||||
|
||||
Exec_expr_op::~Exec_expr_op()
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
Exec_expr_op::alloc(Ctx& ctx, Ctl& ctl)
|
||||
{
|
||||
if (m_data != 0)
|
||||
return;
|
||||
const Code& code = getCode();
|
||||
// allocate subexpressions
|
||||
unsigned arity = code.m_op.arity();
|
||||
for (unsigned i = 1; i <= arity; i++) {
|
||||
ctx_assert(m_expr[i] != 0);
|
||||
m_expr[i]->alloc(ctx, ctl);
|
||||
if (! ctx.ok())
|
||||
return;
|
||||
}
|
||||
SqlField sqlField(code.m_sqlSpec);
|
||||
Data& data = *new Data(sqlField);
|
||||
setData(data);
|
||||
}
|
||||
|
||||
void
|
||||
Exec_expr_op::close(Ctx& ctx)
|
||||
{
|
||||
const Code& code = getCode();
|
||||
unsigned arity = code.m_op.arity();
|
||||
for (unsigned i = 1; i <= arity; i++) {
|
||||
ctx_assert(m_expr[i] != 0);
|
||||
m_expr[i]->close(ctx);
|
||||
}
|
||||
Data& data = getData();
|
||||
data.m_groupField.clear();
|
||||
}
|
||||
|
||||
void
|
||||
Exec_expr_op::print(Ctx& ctx)
|
||||
{
|
||||
const Code& code = getCode();
|
||||
ctx.print(" [%s", code.m_op.name());
|
||||
Exec_base* a[] = { m_expr[1], m_expr[2] };
|
||||
printList(ctx, a, code.m_op.arity());
|
||||
ctx.print("]");
|
||||
}
|
@@ -1,166 +0,0 @@
|
||||
/* Copyright (C) 2003 MySQL AB
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||
|
||||
#ifndef ODBC_CODEGEN_Code_expr_op_hpp
|
||||
#define ODBC_CODEGEN_Code_expr_op_hpp
|
||||
|
||||
#include <common/common.hpp>
|
||||
#include <common/DataField.hpp>
|
||||
#include "Code_expr.hpp"
|
||||
|
||||
/**
|
||||
* @class Expr_op
|
||||
* @brief Arithmetic and string operators
|
||||
*/
|
||||
struct Expr_op {
|
||||
enum Opcode {
|
||||
Add = 1, // binary
|
||||
Subtract,
|
||||
Multiply,
|
||||
Divide,
|
||||
Plus, // unary
|
||||
Minus
|
||||
};
|
||||
Expr_op(Opcode opcode);
|
||||
const char* name() const;
|
||||
unsigned arity() const;
|
||||
Opcode m_opcode;
|
||||
};
|
||||
|
||||
inline
|
||||
Expr_op::Expr_op(Opcode opcode) :
|
||||
m_opcode(opcode)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @class Plan_expr_op
|
||||
* @brief Operator node in an expression in PlanTree
|
||||
*/
|
||||
class Plan_expr_op : public Plan_expr {
|
||||
public:
|
||||
Plan_expr_op(Plan_root* root, Expr_op op);
|
||||
virtual ~Plan_expr_op();
|
||||
Plan_base* analyze(Ctx& ctx, Ctl& ctl);
|
||||
Exec_base* codegen(Ctx& ctx, Ctl& ctl);
|
||||
void print(Ctx& ctx);
|
||||
bool isEqual(const Plan_expr* expr) const;
|
||||
bool isGroupBy(const Plan_expr_row* row) const;
|
||||
// children
|
||||
void setExpr(unsigned i, Plan_expr* expr);
|
||||
protected:
|
||||
Expr_op m_op;
|
||||
Plan_expr* m_expr[1 + 2];
|
||||
};
|
||||
|
||||
inline
|
||||
Plan_expr_op::Plan_expr_op(Plan_root* root, Expr_op op) :
|
||||
Plan_expr(root, TypeOp),
|
||||
m_op(op)
|
||||
{
|
||||
m_expr[0] = m_expr[1] = m_expr[2] = 0;
|
||||
}
|
||||
|
||||
inline void
|
||||
Plan_expr_op::setExpr(unsigned i, Plan_expr* expr)
|
||||
{
|
||||
ctx_assert(1 <= i && i <= 2 && expr != 0);
|
||||
m_expr[i] = expr;
|
||||
}
|
||||
|
||||
/**
|
||||
* @class Exec_expr_op
|
||||
* @brief Operator node in an expression in ExecTree
|
||||
*/
|
||||
class Exec_expr_op : public Exec_expr {
|
||||
public:
|
||||
class Code : public Exec_expr::Code {
|
||||
public:
|
||||
Code(Expr_op op, const SqlSpec& spec);
|
||||
virtual ~Code();
|
||||
protected:
|
||||
friend class Exec_expr_op;
|
||||
Expr_op m_op;
|
||||
const SqlSpec m_sqlSpec;
|
||||
};
|
||||
class Data : public Exec_expr::Data {
|
||||
public:
|
||||
Data(const SqlField& sqlField);
|
||||
virtual ~Data();
|
||||
protected:
|
||||
friend class Exec_expr_op;
|
||||
SqlField m_sqlField;
|
||||
};
|
||||
Exec_expr_op(Exec_root* root);
|
||||
virtual ~Exec_expr_op();
|
||||
void alloc(Ctx& ctx, Ctl& ctl);
|
||||
void evaluate(Ctx& ctx, Ctl& ctl);
|
||||
void close(Ctx& ctx);
|
||||
void print(Ctx& ctx);
|
||||
// children
|
||||
const Code& getCode() const;
|
||||
Data& getData() const;
|
||||
void setExpr(unsigned i, Exec_expr* expr);
|
||||
protected:
|
||||
Exec_expr* m_expr[1 + 2];
|
||||
};
|
||||
|
||||
inline
|
||||
Exec_expr_op::Code::Code(Expr_op op, const SqlSpec& sqlSpec) :
|
||||
Exec_expr::Code(m_sqlSpec),
|
||||
m_op(op),
|
||||
m_sqlSpec(sqlSpec)
|
||||
{
|
||||
}
|
||||
|
||||
inline
|
||||
Exec_expr_op::Data::Data(const SqlField& sqlField) :
|
||||
Exec_expr::Data(m_sqlField),
|
||||
m_sqlField(sqlField)
|
||||
{
|
||||
}
|
||||
|
||||
inline
|
||||
Exec_expr_op::Exec_expr_op(Exec_root* root) :
|
||||
Exec_expr(root)
|
||||
{
|
||||
m_expr[0] = m_expr[1] = m_expr[2] = 0;
|
||||
}
|
||||
|
||||
// children
|
||||
|
||||
inline const Exec_expr_op::Code&
|
||||
Exec_expr_op::getCode() const
|
||||
{
|
||||
const Code* code = static_cast<const Code*>(m_code);
|
||||
return *code;
|
||||
}
|
||||
|
||||
inline Exec_expr_op::Data&
|
||||
Exec_expr_op::getData() const
|
||||
{
|
||||
Data* data = static_cast<Data*>(m_data);
|
||||
return *data;
|
||||
}
|
||||
|
||||
inline void
|
||||
Exec_expr_op::setExpr(unsigned i, Exec_expr* expr)
|
||||
{
|
||||
ctx_assert(1 <= i && i <= 2 && m_expr[i] == 0);
|
||||
m_expr[i] = expr;
|
||||
}
|
||||
|
||||
#endif
|
@@ -1,279 +0,0 @@
|
||||
/* Copyright (C) 2003 MySQL AB
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||
|
||||
#include "Code_expr_param.hpp"
|
||||
#include "Code_root.hpp"
|
||||
|
||||
// Plan_expr_param
|
||||
|
||||
Plan_expr_param::~Plan_expr_param()
|
||||
{
|
||||
}
|
||||
|
||||
Plan_base*
|
||||
Plan_expr_param::analyze(Ctx& ctx, Ctl& ctl)
|
||||
{
|
||||
m_exec = 0;
|
||||
ctx_assert(m_paramNumber != 0);
|
||||
ctx_assert(m_paramNumber < m_root->m_paramList.size());
|
||||
m_root->m_paramList[m_paramNumber] = this;
|
||||
m_sqlType.setType(ctx, SqlType::Unbound);
|
||||
// check if type is bound now
|
||||
DescArea& ipd = descArea(Desc_usage_IPD);
|
||||
if (m_paramNumber <= ipd.getCount()) {
|
||||
DescRec& rec = ipd.getRecord(m_paramNumber);
|
||||
OdbcData descData;
|
||||
rec.getField(ctx, SQL_DESC_TYPE, descData);
|
||||
if (descData.type() != OdbcData::Undef) {
|
||||
SQLSMALLINT desc_TYPE = descData.smallint();
|
||||
// XXX wrong but fixes sun.jdbc.odbc
|
||||
if (desc_TYPE == SQL_CHAR)
|
||||
desc_TYPE = SQL_VARCHAR;
|
||||
if (desc_TYPE == SQL_CHAR) {
|
||||
rec.getField(ctx, SQL_DESC_LENGTH, descData);
|
||||
if (descData.type() != OdbcData::Undef) {
|
||||
unsigned desc_LENGTH = descData.uinteger();
|
||||
m_sqlType.setType(ctx, SqlType::Char, desc_LENGTH);
|
||||
}
|
||||
} else if (desc_TYPE == SQL_VARCHAR) {
|
||||
rec.getField(ctx, SQL_DESC_LENGTH, descData);
|
||||
if (descData.type() != OdbcData::Undef) {
|
||||
unsigned desc_LENGTH = descData.uinteger();
|
||||
m_sqlType.setType(ctx, SqlType::Varchar, desc_LENGTH);
|
||||
}
|
||||
} else if (desc_TYPE == SQL_BINARY) {
|
||||
rec.getField(ctx, SQL_DESC_LENGTH, descData);
|
||||
if (descData.type() != OdbcData::Undef) {
|
||||
unsigned desc_LENGTH = descData.uinteger();
|
||||
m_sqlType.setType(ctx, SqlType::Binary, desc_LENGTH);
|
||||
}
|
||||
} else if (desc_TYPE == SQL_VARBINARY) {
|
||||
rec.getField(ctx, SQL_DESC_LENGTH, descData);
|
||||
if (descData.type() != OdbcData::Undef) {
|
||||
unsigned desc_LENGTH = descData.uinteger();
|
||||
m_sqlType.setType(ctx, SqlType::Varbinary, desc_LENGTH);
|
||||
} else {
|
||||
// XXX BLOB hack
|
||||
unsigned desc_LENGTH = FAKE_BLOB_SIZE;
|
||||
m_sqlType.setType(ctx, SqlType::Varbinary, desc_LENGTH);
|
||||
}
|
||||
} else if (desc_TYPE == SQL_SMALLINT) {
|
||||
m_sqlType.setType(ctx, SqlType::Smallint);
|
||||
} else if (desc_TYPE == SQL_INTEGER) {
|
||||
m_sqlType.setType(ctx, SqlType::Integer);
|
||||
} else if (desc_TYPE == SQL_BIGINT) {
|
||||
m_sqlType.setType(ctx, SqlType::Bigint);
|
||||
} else if (desc_TYPE == SQL_REAL) {
|
||||
m_sqlType.setType(ctx, SqlType::Real);
|
||||
} else if (desc_TYPE == SQL_DOUBLE) {
|
||||
m_sqlType.setType(ctx, SqlType::Double);
|
||||
} else if (desc_TYPE == SQL_TYPE_TIMESTAMP) {
|
||||
m_sqlType.setType(ctx, SqlType::Datetime);
|
||||
// XXX BLOB hack
|
||||
} else if (desc_TYPE == SQL_LONGVARBINARY) {
|
||||
m_sqlType.setType(ctx, SqlType::Varbinary, (unsigned)FAKE_BLOB_SIZE);
|
||||
} else {
|
||||
ctx.pushStatus(Error::Gen, "parameter %u unsupported SQL type %d", m_paramNumber, (int)desc_TYPE);
|
||||
return 0;
|
||||
}
|
||||
char buf[100];
|
||||
m_sqlType.print(buf, sizeof(buf));
|
||||
ctx_log2(("parameter %u SQL type bound to %s", m_paramNumber, buf));
|
||||
}
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
void
|
||||
Plan_expr_param::describe(Ctx& ctx)
|
||||
{
|
||||
DescArea& ipd = descArea(Desc_usage_IPD);
|
||||
if (ipd.getCount() < m_paramNumber)
|
||||
ipd.setCount(ctx, m_paramNumber);
|
||||
// XXX describe if possible
|
||||
DescRec& rec = ipd.getRecord(m_paramNumber);
|
||||
}
|
||||
|
||||
Exec_base*
|
||||
Plan_expr_param::codegen(Ctx& ctx, Ctl& ctl)
|
||||
{
|
||||
if (m_exec != 0)
|
||||
return m_exec;
|
||||
SqlSpec sqlSpec(m_sqlType, SqlSpec::Physical);
|
||||
// create code
|
||||
Exec_expr_param* exec = new Exec_expr_param(ctl.m_execRoot);
|
||||
ctl.m_execRoot->saveNode(exec);
|
||||
ctx_assert(m_paramNumber != 0);
|
||||
Exec_expr_param::Code& code = *new Exec_expr_param::Code(sqlSpec, m_paramNumber);
|
||||
exec->setCode(code);
|
||||
m_exec = exec;
|
||||
return exec;
|
||||
}
|
||||
|
||||
void
|
||||
Plan_expr_param::print(Ctx& ctx)
|
||||
{
|
||||
ctx.print(" [param %u]", m_paramNumber);
|
||||
}
|
||||
|
||||
bool
|
||||
Plan_expr_param::isEqual(const Plan_expr* expr) const
|
||||
{
|
||||
ctx_assert(expr != 0);
|
||||
if (expr->type() != Plan_expr::TypeParam)
|
||||
return false;
|
||||
const Plan_expr_param* expr2 = static_cast<const Plan_expr_param*>(expr);
|
||||
// params are not equal ever
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
Plan_expr_param::isGroupBy(const Plan_expr_row* row) const
|
||||
{
|
||||
// params are constants
|
||||
return true;
|
||||
}
|
||||
|
||||
// Exec_expr_param
|
||||
|
||||
Exec_expr_param::Code::~Code()
|
||||
{
|
||||
}
|
||||
|
||||
Exec_expr_param::Data::~Data()
|
||||
{
|
||||
delete m_extField;
|
||||
m_extField = 0;
|
||||
}
|
||||
|
||||
Exec_expr_param::~Exec_expr_param()
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
Exec_expr_param::alloc(Ctx& ctx, Ctl& ctl)
|
||||
{
|
||||
if (m_data != 0)
|
||||
return;
|
||||
const Code& code = getCode();
|
||||
SqlField sqlField(code.sqlSpec());
|
||||
Data& data = *new Data(sqlField);
|
||||
setData(data);
|
||||
}
|
||||
|
||||
void
|
||||
Exec_expr_param::bind(Ctx& ctx)
|
||||
{
|
||||
const Code& code = getCode();
|
||||
Data& data = getData();
|
||||
DescArea& apd = descArea(Desc_usage_APD);
|
||||
if (apd.getCount() < code.m_paramNumber) {
|
||||
ctx_log1(("parameter %u is not bound", code.m_paramNumber));
|
||||
return;
|
||||
}
|
||||
const unsigned paramNumber = code.m_paramNumber;
|
||||
DescRec& rec = apd.getRecord(paramNumber);
|
||||
OdbcData descData;
|
||||
// create type
|
||||
rec.getField(ctx, SQL_DESC_TYPE, descData);
|
||||
if (descData.type() == OdbcData::Undef) {
|
||||
ctx.pushStatus(Error::Gen, "parameter %u external type not defined", paramNumber);
|
||||
return;
|
||||
}
|
||||
ExtType extType;
|
||||
SQLSMALLINT desc_TYPE = descData.smallint();
|
||||
switch (desc_TYPE) {
|
||||
case SQL_C_CHAR:
|
||||
case SQL_C_SHORT: // for sun.jdbc.odbc
|
||||
case SQL_C_SSHORT:
|
||||
case SQL_C_USHORT:
|
||||
case SQL_C_LONG: // for sun.jdbc.odbc
|
||||
case SQL_C_SLONG:
|
||||
case SQL_C_ULONG:
|
||||
case SQL_C_SBIGINT:
|
||||
case SQL_C_UBIGINT:
|
||||
case SQL_C_FLOAT:
|
||||
case SQL_C_DOUBLE:
|
||||
case SQL_C_TYPE_TIMESTAMP:
|
||||
case SQL_C_BINARY: // XXX BLOB hack
|
||||
break;
|
||||
default:
|
||||
ctx.pushStatus(Error::Gen, "parameter %u unsupported external type %d", paramNumber, (int)desc_TYPE);
|
||||
return;
|
||||
}
|
||||
extType.setType(ctx, static_cast<ExtType::Type>(desc_TYPE));
|
||||
ExtSpec extSpec(extType);
|
||||
// create data field
|
||||
rec.getField(ctx, SQL_DESC_DATA_PTR, descData);
|
||||
if (descData.type() == OdbcData::Undef) {
|
||||
ctx.pushStatus(Error::Gen, "parameter %u data address not defined", paramNumber);
|
||||
return;
|
||||
}
|
||||
SQLPOINTER desc_DATA_PTR = descData.pointer();
|
||||
rec.getField(ctx, SQL_DESC_OCTET_LENGTH, descData);
|
||||
if (descData.type() == OdbcData::Undef) {
|
||||
ctx.pushStatus(Error::Gen, "parameter %u data length not defined", paramNumber);
|
||||
return;
|
||||
}
|
||||
SQLINTEGER desc_OCTET_LENGTH = descData.integer();
|
||||
rec.getField(ctx, SQL_DESC_INDICATOR_PTR, descData);
|
||||
if (descData.type() == OdbcData::Undef) {
|
||||
ctx.pushStatus(Error::Gen, "parameter %u indicator address not defined", paramNumber);
|
||||
return;
|
||||
}
|
||||
SQLINTEGER* desc_INDICATOR_PTR = descData.integerPtr();
|
||||
ctx_log4(("parameter %u bind to 0x%x %d 0x%x", paramNumber, (unsigned)desc_DATA_PTR, (int)desc_OCTET_LENGTH, (unsigned)desc_INDICATOR_PTR));
|
||||
ExtField& extField = *new ExtField(extSpec, desc_DATA_PTR, desc_OCTET_LENGTH, desc_INDICATOR_PTR, paramNumber);
|
||||
data.m_atExec = false;
|
||||
if (desc_INDICATOR_PTR != 0 && *desc_INDICATOR_PTR < 0) {
|
||||
if (*desc_INDICATOR_PTR == SQL_NULL_DATA) {
|
||||
;
|
||||
} else if (*desc_INDICATOR_PTR == SQL_DATA_AT_EXEC) {
|
||||
data.m_atExec = true;
|
||||
} else if (*desc_INDICATOR_PTR <= SQL_LEN_DATA_AT_EXEC(0)) {
|
||||
data.m_atExec = true;
|
||||
}
|
||||
}
|
||||
delete data.m_extField;
|
||||
data.m_extField = &extField;
|
||||
}
|
||||
|
||||
void
|
||||
Exec_expr_param::evaluate(Ctx& ctx, Ctl& ctl)
|
||||
{
|
||||
if (ctl.m_postEval)
|
||||
return;
|
||||
const Code& code = getCode();
|
||||
Data& data = getData();
|
||||
if (data.m_atExec)
|
||||
return;
|
||||
ctx_assert(data.m_extField != 0);
|
||||
data.m_sqlField.copyin(ctx, *data.m_extField);
|
||||
}
|
||||
|
||||
void
|
||||
Exec_expr_param::close(Ctx& ctx)
|
||||
{
|
||||
Data& data = getData();
|
||||
data.m_extPos = -1;
|
||||
}
|
||||
|
||||
void
|
||||
Exec_expr_param::print(Ctx& ctx)
|
||||
{
|
||||
const Code& code = getCode();
|
||||
ctx.print(" [param %u]", code.m_paramNumber);
|
||||
}
|
@@ -1,136 +0,0 @@
|
||||
/* Copyright (C) 2003 MySQL AB
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||
|
||||
#ifndef ODBC_CODEGEN_Code_expr_param_hpp
|
||||
#define ODBC_CODEGEN_Code_expr_param_hpp
|
||||
|
||||
#include <common/common.hpp>
|
||||
#include <common/DataField.hpp>
|
||||
#include "Code_expr.hpp"
|
||||
|
||||
/**
|
||||
* @class Plan_expr_param
|
||||
* @brief Constant expression value in PlanTree
|
||||
*/
|
||||
class Plan_expr_param : public Plan_expr {
|
||||
public:
|
||||
Plan_expr_param(Plan_root* root, unsigned paramNumber);
|
||||
virtual ~Plan_expr_param();
|
||||
Plan_base* analyze(Ctx& ctx, Ctl& ctl);
|
||||
void describe(Ctx& ctx);
|
||||
Exec_base* codegen(Ctx& ctx, Ctl& ctl);
|
||||
void print(Ctx& ctx);
|
||||
bool isEqual(const Plan_expr* expr) const;
|
||||
bool isGroupBy(const Plan_expr_row* row) const;
|
||||
protected:
|
||||
const unsigned m_paramNumber;
|
||||
};
|
||||
|
||||
inline
|
||||
Plan_expr_param::Plan_expr_param(Plan_root* root, unsigned paramNumber) :
|
||||
Plan_expr(root, TypeParam),
|
||||
m_paramNumber(paramNumber)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @class Exec_expr_param
|
||||
* @brief Constant expression value in ExecTree
|
||||
*/
|
||||
class Exec_expr_param : public Exec_expr {
|
||||
public:
|
||||
class Code : public Exec_expr::Code {
|
||||
public:
|
||||
Code(const SqlSpec& sqlSpec, unsigned paramNumber);
|
||||
virtual ~Code();
|
||||
protected:
|
||||
friend class Plan_expr_param;
|
||||
friend class Exec_expr_param;
|
||||
const SqlSpec m_sqlSpec;
|
||||
const unsigned m_paramNumber;
|
||||
};
|
||||
class Data : public Exec_expr::Data {
|
||||
public:
|
||||
Data(SqlField& sqlField);
|
||||
virtual ~Data();
|
||||
ExtField* extField() const;
|
||||
protected:
|
||||
friend class Exec_expr_param;
|
||||
friend class Exec_root;
|
||||
SqlField m_sqlField;
|
||||
ExtField* m_extField; // input binding
|
||||
bool m_atExec; // data at exec
|
||||
int m_extPos; // position for SQLPutData (-1 before first call)
|
||||
};
|
||||
Exec_expr_param(Exec_root* root);
|
||||
virtual ~Exec_expr_param();
|
||||
void alloc(Ctx& ctx, Ctl& ctl);
|
||||
void bind(Ctx& ctx);
|
||||
void evaluate(Ctx& ctx, Ctl& ctl);
|
||||
void close(Ctx& ctx);
|
||||
void print(Ctx& ctx);
|
||||
// children
|
||||
const Code& getCode() const;
|
||||
Data& getData() const;
|
||||
};
|
||||
|
||||
inline
|
||||
Exec_expr_param::Code::Code(const SqlSpec& sqlSpec, unsigned paramNumber) :
|
||||
Exec_expr::Code(m_sqlSpec),
|
||||
m_sqlSpec(sqlSpec),
|
||||
m_paramNumber(paramNumber)
|
||||
{
|
||||
}
|
||||
|
||||
inline
|
||||
Exec_expr_param::Data::Data(SqlField& sqlField) :
|
||||
Exec_expr::Data(m_sqlField),
|
||||
m_sqlField(sqlField),
|
||||
m_extField(0),
|
||||
m_atExec(false),
|
||||
m_extPos(-1)
|
||||
{
|
||||
}
|
||||
|
||||
inline ExtField*
|
||||
Exec_expr_param::Data::extField() const
|
||||
{
|
||||
return m_extField;
|
||||
}
|
||||
|
||||
inline
|
||||
Exec_expr_param::Exec_expr_param(Exec_root* root) :
|
||||
Exec_expr(root)
|
||||
{
|
||||
}
|
||||
|
||||
// children
|
||||
|
||||
inline const Exec_expr_param::Code&
|
||||
Exec_expr_param::getCode() const
|
||||
{
|
||||
const Code* code = static_cast<const Code*>(m_code);
|
||||
return *code;
|
||||
}
|
||||
|
||||
inline Exec_expr_param::Data&
|
||||
Exec_expr_param::getData() const
|
||||
{
|
||||
Data* data = static_cast<Data*>(m_data);
|
||||
return *data;
|
||||
}
|
||||
|
||||
#endif
|
@@ -1,204 +0,0 @@
|
||||
/* Copyright (C) 2003 MySQL AB
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||
|
||||
#include <common/DataType.hpp>
|
||||
#include "Code_expr_row.hpp"
|
||||
#include "Code_expr.hpp"
|
||||
#include "Code_expr_conv.hpp"
|
||||
#include "Code_dml_row.hpp"
|
||||
#include "Code_root.hpp"
|
||||
|
||||
// Plan_expr_row
|
||||
|
||||
Plan_expr_row::~Plan_expr_row()
|
||||
{
|
||||
}
|
||||
|
||||
Plan_base*
|
||||
Plan_expr_row::analyze(Ctx& ctx, Ctl& ctl)
|
||||
{
|
||||
unsigned size = getSize();
|
||||
// analyze subexpressions
|
||||
m_anyAggr = false;
|
||||
m_allBound = true;
|
||||
for (unsigned i = 1; i <= size; i++) {
|
||||
Plan_expr* expr1 = getExpr(i);
|
||||
Plan_expr* expr2 = static_cast<Plan_expr*>(expr1->analyze(ctx, ctl));
|
||||
if (! ctx.ok())
|
||||
return 0;
|
||||
setExpr(i, expr2);
|
||||
if (expr2->isAggr())
|
||||
m_anyAggr = true;
|
||||
if (! expr2->isBound())
|
||||
m_allBound = false;
|
||||
}
|
||||
// insert conversions if requested XXX ugly hack
|
||||
if (ctl.m_dmlRow != 0) {
|
||||
if (ctl.m_dmlRow->getSize() > getSize()) {
|
||||
ctx.pushStatus(Sqlstate::_21S01, Error::Gen, "not enough values (%u > %u)", ctl.m_dmlRow->getSize(), getSize());
|
||||
return 0;
|
||||
}
|
||||
if (ctl.m_dmlRow->getSize() < getSize()) {
|
||||
ctx.pushStatus(Sqlstate::_21S01, Error::Gen, "too many values (%u < %u)", ctl.m_dmlRow->getSize(), getSize());
|
||||
return 0;
|
||||
}
|
||||
for (unsigned i = 1; i <= size; i++) {
|
||||
const SqlType& sqlType = ctl.m_dmlRow->getColumn(i)->sqlType();
|
||||
Plan_expr_conv* exprConv = new Plan_expr_conv(m_root, sqlType);
|
||||
m_root->saveNode(exprConv);
|
||||
exprConv->setExpr(getExpr(i));
|
||||
Plan_expr* expr = static_cast<Plan_expr*>(exprConv->analyze(ctx, ctl));
|
||||
if (! ctx.ok())
|
||||
return 0;
|
||||
ctx_assert(expr != 0);
|
||||
setExpr(i, expr);
|
||||
}
|
||||
}
|
||||
// set aliases
|
||||
m_aliasList.resize(1 + size);
|
||||
for (unsigned i = 1; i <= size; i++) {
|
||||
if (m_aliasList[i].empty()) {
|
||||
setAlias(i, getExpr(i)->getAlias());
|
||||
}
|
||||
}
|
||||
// node was not replaced
|
||||
return this;
|
||||
}
|
||||
|
||||
Exec_base*
|
||||
Plan_expr_row::codegen(Ctx& ctx, Ctl& ctl)
|
||||
{
|
||||
unsigned size = getSize();
|
||||
Exec_expr_row* exec = new Exec_expr_row(ctl.m_execRoot, size);
|
||||
ctl.m_execRoot->saveNode(exec);
|
||||
SqlSpecs sqlSpecs(size);
|
||||
// create code for subexpressions
|
||||
for (unsigned i = 1; i <= size; i++) {
|
||||
Plan_expr* planExpr = getExpr(i);
|
||||
Exec_expr* execExpr = static_cast<Exec_expr*>(planExpr->codegen(ctx, ctl));
|
||||
if (! ctx.ok())
|
||||
return 0;
|
||||
ctx_assert(execExpr != 0);
|
||||
exec->setExpr(i, execExpr);
|
||||
const SqlSpec sqlSpec(execExpr->getCode().sqlSpec(), SqlSpec::Reference);
|
||||
sqlSpecs.setEntry(i, sqlSpec);
|
||||
}
|
||||
// create alias list
|
||||
Exec_expr_row::Code::Alias* aliasList = new Exec_expr_row::Code::Alias[1 + size];
|
||||
strcpy(aliasList[0], "?");
|
||||
for (unsigned i = 1; i <= size; i++) {
|
||||
const char* s = m_aliasList[i].c_str();
|
||||
if (strlen(s) == 0)
|
||||
s = getExpr(i)->getAlias().c_str();
|
||||
unsigned n = strlen(s);
|
||||
if (n >= sizeof(Exec_expr_row::Code::Alias))
|
||||
n = sizeof(Exec_expr_row::Code::Alias) - 1;
|
||||
strncpy(aliasList[i], s, n);
|
||||
aliasList[i][n] = 0;
|
||||
}
|
||||
// create the code
|
||||
Exec_expr_row::Code& code = *new Exec_expr_row::Code(sqlSpecs, aliasList);
|
||||
exec->setCode(code);
|
||||
return exec;
|
||||
}
|
||||
|
||||
void
|
||||
Plan_expr_row::print(Ctx& ctx)
|
||||
{
|
||||
const unsigned size = getSize();
|
||||
ctx.print(" [expr_row");
|
||||
for (unsigned i = 1; i <= size; i++) {
|
||||
Plan_base* a = m_exprList[i];
|
||||
a == 0 ? ctx.print(" -") : a->print(ctx);
|
||||
}
|
||||
ctx.print("]");
|
||||
}
|
||||
|
||||
bool
|
||||
Plan_expr_row::isAllGroupBy(const Plan_expr_row* row) const
|
||||
{
|
||||
const unsigned size = getSize();
|
||||
for (unsigned i = 1; i <= size; i++) {
|
||||
if (! getExpr(i)->isGroupBy(row))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// Exec_expr_row
|
||||
|
||||
Exec_expr_row::Code::~Code()
|
||||
{
|
||||
delete[] m_aliasList;
|
||||
}
|
||||
|
||||
Exec_expr_row::Data::~Data()
|
||||
{
|
||||
}
|
||||
|
||||
Exec_expr_row::~Exec_expr_row()
|
||||
{
|
||||
delete[] m_expr;
|
||||
}
|
||||
|
||||
void
|
||||
Exec_expr_row::alloc(Ctx& ctx, Ctl& ctl)
|
||||
{
|
||||
// allocate subexpressions
|
||||
for (unsigned i = 1; i <= m_size; i++) {
|
||||
getExpr(i)->alloc(ctx, ctl);
|
||||
}
|
||||
// construct SqlRow of references
|
||||
const Code& code = getCode();
|
||||
SqlRow sqlRow(getCode().m_sqlSpecs);
|
||||
for (unsigned i = 1; i <= m_size; i++) {
|
||||
const Exec_expr::Data& dataExpr = getExpr(i)->getData();
|
||||
const SqlSpec& sqlSpec = code.m_sqlSpecs.getEntry(i);
|
||||
const SqlField sqlField(sqlSpec, &dataExpr.sqlField());
|
||||
sqlRow.setEntry(i, sqlField);
|
||||
}
|
||||
// create the data
|
||||
Data& data = *new Data(sqlRow);
|
||||
setData(data);
|
||||
}
|
||||
|
||||
void
|
||||
Exec_expr_row::evaluate(Ctx& ctx, Ctl& ctl)
|
||||
{
|
||||
for (unsigned i = 1; i <= m_size; i++) {
|
||||
getExpr(i)->evaluate(ctx, ctl);
|
||||
if (! ctx.ok())
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Exec_expr_row::close(Ctx& ctx)
|
||||
{
|
||||
for (unsigned i = 1; i <= m_size; i++) {
|
||||
getExpr(i)->close(ctx);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Exec_expr_row::print(Ctx& ctx)
|
||||
{
|
||||
ctx.print(" [expr_row");
|
||||
for (unsigned i = 1; i <= m_size; i++) {
|
||||
getExpr(i)->print(ctx);
|
||||
}
|
||||
ctx.print("]");
|
||||
}
|
@@ -1,272 +0,0 @@
|
||||
/* Copyright (C) 2003 MySQL AB
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||
|
||||
#ifndef ODBC_CODEGEN_Code_expr_row_hpp
|
||||
#define ODBC_CODEGEN_Code_expr_row_hpp
|
||||
|
||||
#include <vector>
|
||||
#include <common/common.hpp>
|
||||
#include <common/DataRow.hpp>
|
||||
#include "Code_base.hpp"
|
||||
#include "Code_expr.hpp"
|
||||
|
||||
class Plan_expr;
|
||||
|
||||
/**
|
||||
* @class Plan_expr_row
|
||||
* @brief Row of expressions in PlanTree
|
||||
*
|
||||
* Used for select, value, and order by rows.
|
||||
*/
|
||||
class Plan_expr_row : public Plan_base {
|
||||
public:
|
||||
Plan_expr_row(Plan_root* root);
|
||||
virtual ~Plan_expr_row();
|
||||
Plan_base* analyze(Ctx& ctx, Ctl& ctl);
|
||||
Exec_base* codegen(Ctx& ctx, Ctl& ctl);
|
||||
void print(Ctx& ctx);
|
||||
// children
|
||||
void setAsterisk();
|
||||
bool getAsterisk() const;
|
||||
unsigned getSize() const;
|
||||
Plan_expr* getExpr(unsigned i) const;
|
||||
void setExpr(unsigned i, Plan_expr* expr);
|
||||
void addExpr(Plan_expr* expr);
|
||||
void addExpr(Plan_expr* expr, const BaseString& alias);
|
||||
void setAlias(unsigned i, const BaseString& alias);
|
||||
void addExpr(Plan_expr* expr, bool asc);
|
||||
bool anyAggr() const;
|
||||
bool allBound() const;
|
||||
bool isAllGroupBy(const Plan_expr_row* row) const;
|
||||
protected:
|
||||
friend class Plan_query;
|
||||
friend class Plan_query_sort;
|
||||
bool m_asterisk; // early plan node type
|
||||
ExprVector m_exprList;
|
||||
typedef std::vector<BaseString> AliasList;
|
||||
AliasList m_aliasList;
|
||||
typedef std::vector<bool> AscList;
|
||||
AscList m_ascList;
|
||||
bool m_anyAggr; // at least one aggreate
|
||||
bool m_allBound; // all bound
|
||||
};
|
||||
|
||||
inline
|
||||
Plan_expr_row::Plan_expr_row(Plan_root* root) :
|
||||
Plan_base(root),
|
||||
m_asterisk(false),
|
||||
m_exprList(1),
|
||||
m_aliasList(1),
|
||||
m_ascList(1),
|
||||
m_anyAggr(false),
|
||||
m_allBound(false)
|
||||
{
|
||||
}
|
||||
|
||||
// children
|
||||
|
||||
inline void
|
||||
Plan_expr_row::setAsterisk()
|
||||
{
|
||||
m_asterisk = true;
|
||||
}
|
||||
|
||||
inline bool
|
||||
Plan_expr_row::getAsterisk() const
|
||||
{
|
||||
return m_asterisk;
|
||||
}
|
||||
|
||||
inline unsigned
|
||||
Plan_expr_row::getSize() const
|
||||
{
|
||||
ctx_assert(m_exprList.size() >= 1);
|
||||
return m_exprList.size() - 1;
|
||||
}
|
||||
|
||||
inline void
|
||||
Plan_expr_row::addExpr(Plan_expr* expr)
|
||||
{
|
||||
ctx_assert(expr != 0);
|
||||
addExpr(expr, expr->m_alias);
|
||||
}
|
||||
|
||||
inline void
|
||||
Plan_expr_row::addExpr(Plan_expr* expr, const BaseString& alias)
|
||||
{
|
||||
ctx_assert(expr != 0);
|
||||
m_exprList.push_back(expr);
|
||||
m_aliasList.push_back(alias);
|
||||
}
|
||||
|
||||
inline void
|
||||
Plan_expr_row::addExpr(Plan_expr* expr, bool asc)
|
||||
{
|
||||
ctx_assert(expr != 0);
|
||||
m_exprList.push_back(expr);
|
||||
m_ascList.push_back(asc);
|
||||
}
|
||||
|
||||
inline void
|
||||
Plan_expr_row::setExpr(unsigned i, Plan_expr* expr)
|
||||
{
|
||||
ctx_assert(1 <= i && i < m_exprList.size() && expr != 0);
|
||||
m_exprList[i] = expr;
|
||||
}
|
||||
|
||||
inline Plan_expr*
|
||||
Plan_expr_row::getExpr(unsigned i) const
|
||||
{
|
||||
ctx_assert(1 <= i && i < m_exprList.size() && m_exprList[i] != 0);
|
||||
return m_exprList[i];
|
||||
}
|
||||
|
||||
inline void
|
||||
Plan_expr_row::setAlias(unsigned i, const BaseString& alias)
|
||||
{
|
||||
ctx_assert(1 <= i && i < m_aliasList.size());
|
||||
m_aliasList[i] = alias;
|
||||
}
|
||||
|
||||
inline bool
|
||||
Plan_expr_row::anyAggr() const
|
||||
{
|
||||
return m_anyAggr;
|
||||
}
|
||||
|
||||
inline bool
|
||||
Plan_expr_row::allBound() const
|
||||
{
|
||||
return m_allBound;
|
||||
}
|
||||
|
||||
/**
|
||||
* @class Expr_expr_row
|
||||
* @brief Row of expressions in ExecTree
|
||||
*/
|
||||
class Exec_expr_row : public Exec_base {
|
||||
public:
|
||||
class Code : public Exec_base::Code {
|
||||
public:
|
||||
typedef char Alias[40];
|
||||
Code(const SqlSpecs& sqlSpecs, const Alias* aliasList);
|
||||
virtual ~Code();
|
||||
const SqlSpecs& sqlSpecs() const;
|
||||
const char* getAlias(unsigned i) const;
|
||||
protected:
|
||||
friend class Exec_expr_row;
|
||||
const SqlSpecs m_sqlSpecs;
|
||||
const Alias* m_aliasList;
|
||||
};
|
||||
class Data : public Exec_base::Data {
|
||||
public:
|
||||
Data(const SqlRow& sqlRow);
|
||||
virtual ~Data();
|
||||
const SqlRow& sqlRow() const;
|
||||
protected:
|
||||
friend class Exec_expr_row;
|
||||
SqlRow m_sqlRow;
|
||||
};
|
||||
Exec_expr_row(Exec_root* root, unsigned size);
|
||||
virtual ~Exec_expr_row();
|
||||
void alloc(Ctx& ctx, Ctl& ctl);
|
||||
void evaluate(Ctx& ctx, Ctl& ctl);
|
||||
void close(Ctx& ctx);
|
||||
void print(Ctx& ctx);
|
||||
// children
|
||||
const Code& getCode() const;
|
||||
Data& getData() const;
|
||||
Exec_expr* getExpr(unsigned i) const;
|
||||
void setExpr(unsigned i, Exec_expr* expr);
|
||||
protected:
|
||||
Exec_expr** m_expr; // numbered from 1
|
||||
unsigned m_size;
|
||||
};
|
||||
|
||||
inline
|
||||
Exec_expr_row::Code::Code(const SqlSpecs& sqlSpecs, const Alias* aliasList) :
|
||||
m_sqlSpecs(sqlSpecs),
|
||||
m_aliasList(aliasList)
|
||||
{
|
||||
}
|
||||
|
||||
inline const SqlSpecs&
|
||||
Exec_expr_row::Code::sqlSpecs() const
|
||||
{
|
||||
return m_sqlSpecs;
|
||||
}
|
||||
|
||||
inline const char*
|
||||
Exec_expr_row::Code::getAlias(unsigned i) const
|
||||
{
|
||||
ctx_assert(1 <= i && i <= m_sqlSpecs.count() && m_aliasList != 0);
|
||||
return m_aliasList[i];
|
||||
}
|
||||
|
||||
inline
|
||||
Exec_expr_row::Data::Data(const SqlRow& sqlRow) :
|
||||
m_sqlRow(sqlRow)
|
||||
{
|
||||
}
|
||||
|
||||
inline const SqlRow&
|
||||
Exec_expr_row::Data::sqlRow() const
|
||||
{
|
||||
return m_sqlRow;
|
||||
}
|
||||
|
||||
inline
|
||||
Exec_expr_row::Exec_expr_row(Exec_root* root, unsigned size) :
|
||||
Exec_base(root),
|
||||
m_expr(new Exec_expr* [1 + size]),
|
||||
m_size(size)
|
||||
{
|
||||
m_expr[0] = (Exec_expr*)-1;
|
||||
for (unsigned i = 1; i <= m_size; i++)
|
||||
m_expr[i] = 0;
|
||||
}
|
||||
|
||||
// children
|
||||
|
||||
inline const Exec_expr_row::Code&
|
||||
Exec_expr_row::getCode() const
|
||||
{
|
||||
const Code* code = static_cast<const Code*>(m_code);
|
||||
return *code;
|
||||
}
|
||||
|
||||
inline Exec_expr_row::Data&
|
||||
Exec_expr_row::getData() const
|
||||
{
|
||||
Data* data = static_cast<Data*>(m_data);
|
||||
return *data;
|
||||
}
|
||||
|
||||
inline Exec_expr*
|
||||
Exec_expr_row::getExpr(unsigned i) const
|
||||
{
|
||||
ctx_assert(1 <= i && i <= m_size && m_expr != 0 && m_expr[i] != 0);
|
||||
return m_expr[i];
|
||||
}
|
||||
|
||||
inline void
|
||||
Exec_expr_row::setExpr(unsigned i, Exec_expr* expr)
|
||||
{
|
||||
ctx_assert(1 <= i && i <= m_size && m_expr != 0 && m_expr[i] == 0);
|
||||
m_expr[i] = expr;
|
||||
}
|
||||
|
||||
#endif
|
@@ -1,49 +0,0 @@
|
||||
/* Copyright (C) 2003 MySQL AB
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||
|
||||
#include <NdbApi.hpp>
|
||||
#include <common/StmtArea.hpp>
|
||||
#include "Code_idx_column.hpp"
|
||||
#include "Code_expr_conv.hpp"
|
||||
#include "Code_root.hpp"
|
||||
|
||||
// Plan_idx_column
|
||||
|
||||
Plan_idx_column::~Plan_idx_column()
|
||||
{
|
||||
}
|
||||
|
||||
Plan_base*
|
||||
Plan_idx_column::analyze(Ctx& ctx, Ctl& ctl)
|
||||
{
|
||||
analyzeColumn(ctx, ctl);
|
||||
if (! ctx.ok())
|
||||
return 0;
|
||||
return this;
|
||||
}
|
||||
|
||||
Exec_base*
|
||||
Plan_idx_column::codegen(Ctx& ctx, Ctl& ctl)
|
||||
{
|
||||
ctx_assert(false);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
Plan_idx_column::print(Ctx& ctx)
|
||||
{
|
||||
ctx.print(" [idx_column %s]", getPrintName());
|
||||
}
|
@@ -1,50 +0,0 @@
|
||||
/* Copyright (C) 2003 MySQL AB
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||
|
||||
#ifndef ODBC_CODEGEN_Code_idx_column_hpp
|
||||
#define ODBC_CODEGEN_Code_idx_column_hpp
|
||||
|
||||
#include <common/common.hpp>
|
||||
#include "Code_column.hpp"
|
||||
#include "Code_data_type.hpp"
|
||||
#include "Code_expr.hpp"
|
||||
|
||||
class DictColumn;
|
||||
class Plan_table;
|
||||
|
||||
/**
|
||||
* @class Plan_idx_column
|
||||
* @brief Column in create index statement
|
||||
*/
|
||||
class Plan_idx_column : public Plan_base, public Plan_column {
|
||||
public:
|
||||
Plan_idx_column(Plan_root* root, const BaseString& name);
|
||||
virtual ~Plan_idx_column();
|
||||
Plan_base* analyze(Ctx& ctx, Ctl& ctl);
|
||||
Exec_base* codegen(Ctx& ctx, Ctl& ctl);
|
||||
void print(Ctx& ctx);
|
||||
protected:
|
||||
friend class Plan_create_row;
|
||||
};
|
||||
|
||||
inline
|
||||
Plan_idx_column::Plan_idx_column(Plan_root* root, const BaseString& name) :
|
||||
Plan_base(root),
|
||||
Plan_column(Type_idx, name)
|
||||
{
|
||||
}
|
||||
|
||||
#endif
|
@@ -1,253 +0,0 @@
|
||||
/* Copyright (C) 2003 MySQL AB
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||
|
||||
#include <common/StmtArea.hpp>
|
||||
#include <dictionary/DictTable.hpp>
|
||||
#include <dictionary/DictColumn.hpp>
|
||||
#include "Code_insert.hpp"
|
||||
#include "Code_query_repeat.hpp"
|
||||
#include "Code_query_project.hpp"
|
||||
#include "Code_table.hpp"
|
||||
#include "Code_root.hpp"
|
||||
|
||||
// Plan_insert
|
||||
|
||||
Plan_insert::~Plan_insert()
|
||||
{
|
||||
}
|
||||
|
||||
Plan_base*
|
||||
Plan_insert::analyze(Ctx& ctx, Ctl& ctl)
|
||||
{
|
||||
stmtArea().stmtInfo().setName(Stmt_name_insert);
|
||||
ctx_assert(m_table != 0);
|
||||
m_table->analyze(ctx, ctl);
|
||||
if (! ctx.ok())
|
||||
return 0;
|
||||
// handle MySql syntax
|
||||
if (m_mysqlRow != 0) {
|
||||
setDmlRow(m_mysqlRow->m_dmlRow);
|
||||
setExprRow(m_mysqlRow->m_exprRow);
|
||||
m_mysqlRow = 0;
|
||||
}
|
||||
if (m_dmlRow == 0) {
|
||||
// construct column list
|
||||
setDmlRow(new Plan_dml_row(m_root));
|
||||
m_root->saveNode(m_dmlRow);
|
||||
const DictTable& dictTable = m_table->dictTable();
|
||||
unsigned n = dictTable.getSize();
|
||||
for (unsigned i = 1; i <= n; i++) {
|
||||
DictColumn* dictColumn = dictTable.getColumn(i);
|
||||
Plan_dml_column* column = new Plan_dml_column(m_root, dictColumn->getName());
|
||||
m_root->saveNode(column);
|
||||
m_dmlRow->addColumn(column);
|
||||
}
|
||||
}
|
||||
// set name resolution scope
|
||||
ctl.m_tableList.resize(1 + 1); // indexed from 1
|
||||
ctl.m_tableList[1] = m_table;
|
||||
// analyze the dml columns
|
||||
m_dmlRow->analyze(ctx, ctl);
|
||||
if (! ctx.ok())
|
||||
return 0;
|
||||
ctl.m_dmlRow = m_dmlRow; // row type to convert to
|
||||
if (m_query != 0) {
|
||||
m_query->analyze(ctx, ctl);
|
||||
if (! ctx.ok())
|
||||
return 0;
|
||||
} else if (m_select == 0) {
|
||||
// analyze the expression row
|
||||
m_exprRow->analyze(ctx, ctl);
|
||||
if (! ctx.ok())
|
||||
return 0;
|
||||
// transform the row into query
|
||||
Plan_query_repeat* queryRepeat = new Plan_query_repeat(m_root, 1);
|
||||
m_root->saveNode(queryRepeat);
|
||||
Plan_query_project* queryProject = new Plan_query_project(m_root);
|
||||
m_root->saveNode(queryProject);
|
||||
queryProject->setQuery(queryRepeat);
|
||||
queryProject->setRow(m_exprRow);
|
||||
setQuery(queryProject);
|
||||
} else {
|
||||
// analyze the select into query
|
||||
Plan_query* query = static_cast<Plan_query*>(m_select->analyze(ctx, ctl));
|
||||
if (! ctx.ok())
|
||||
return 0;
|
||||
setQuery(query);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
void
|
||||
Plan_insert::describe(Ctx& ctx)
|
||||
{
|
||||
stmtArea().setFunction(ctx, "INSERT", SQL_DIAG_INSERT);
|
||||
}
|
||||
|
||||
Exec_base*
|
||||
Plan_insert::codegen(Ctx& ctx, Ctl& ctl)
|
||||
{
|
||||
// create code for the query
|
||||
ctx_assert(m_query != 0);
|
||||
Exec_query* execQuery = static_cast<Exec_query*>(m_query->codegen(ctx, ctl));
|
||||
if (! ctx.ok())
|
||||
return 0;
|
||||
ctx_assert(execQuery != 0);
|
||||
// set up
|
||||
ctx_assert(m_table != 0);
|
||||
const BaseString& tableName = m_table->getName();
|
||||
const DictTable& dictTable = m_table->dictTable();
|
||||
const ColumnVector& columns = m_table->dmlColumns();
|
||||
ctx_assert(columns.size() > 0);
|
||||
const unsigned attrCount = columns.size() - 1;
|
||||
// create the code
|
||||
Exec_insert::Code& code = *new Exec_insert::Code();
|
||||
code.m_insertOp = m_insertOp;
|
||||
code.m_tableName = strcpy(new char[tableName.length() + 1], tableName.c_str());
|
||||
code.m_attrCount = attrCount;
|
||||
code.m_attrId = new NdbAttrId[1 + attrCount];
|
||||
code.m_isKey = new bool[1 + attrCount];
|
||||
code.m_attrId[0] = (NdbAttrId)-1;
|
||||
code.m_tupleId = dictTable.tupleId(); // maybe 0
|
||||
code.m_autoIncrement = dictTable.autoIncrement(); // maybe 0
|
||||
unsigned k;
|
||||
if ((k = code.m_tupleId) != 0 || (k = code.m_autoIncrement) != 0) {
|
||||
const DictColumn& dictColumn = *dictTable.getColumn(k);
|
||||
code.m_idType = dictColumn.sqlType();
|
||||
}
|
||||
for (unsigned i = 1; i <= attrCount; i++) {
|
||||
Plan_column* column = columns[i];
|
||||
ctx_assert(column != 0);
|
||||
const DictColumn& dictColumn = column->dictColumn();
|
||||
code.m_attrId[i] = dictColumn.getAttrId();
|
||||
code.m_isKey[i] = dictColumn.isKey();
|
||||
}
|
||||
// default values XXX a mess
|
||||
code.m_defaultCount = 0;
|
||||
for (unsigned j = 1; j <= dictTable.getSize(); j++) {
|
||||
const DictColumn& dictColumn = *dictTable.getColumn(j);
|
||||
if (dictColumn.getDefaultValue() != 0 && ! code.findAttrId(dictColumn.getAttrId()))
|
||||
code.m_defaultCount++;
|
||||
}
|
||||
if (code.m_defaultCount != 0) {
|
||||
code.m_defaultId = new NdbAttrId[1 + code.m_defaultCount];
|
||||
for (unsigned i = 0, j = 1; j <= dictTable.getSize(); j++) {
|
||||
const DictColumn& dictColumn = *dictTable.getColumn(j);
|
||||
if (dictColumn.getDefaultValue() != 0 && ! code.findAttrId(dictColumn.getAttrId()))
|
||||
code.m_defaultId[++i] = dictColumn.getAttrId();
|
||||
}
|
||||
SqlSpecs sqlSpecs(code.m_defaultCount);
|
||||
for (unsigned i = 0, j = 1; j <= dictTable.getSize(); j++) {
|
||||
const DictColumn& dictColumn = *dictTable.getColumn(j);
|
||||
if (dictColumn.getDefaultValue() != 0 && ! code.findAttrId(dictColumn.getAttrId())) {
|
||||
SqlSpec sqlSpec(dictColumn.sqlType(), SqlSpec::Physical);
|
||||
sqlSpecs.setEntry(++i, sqlSpec);
|
||||
}
|
||||
}
|
||||
code.m_defaultValue = new SqlRow(sqlSpecs);
|
||||
for (unsigned i = 0, j = 1; j <= dictTable.getSize(); j++) {
|
||||
const DictColumn& dictColumn = *dictTable.getColumn(j);
|
||||
if (dictColumn.getDefaultValue() != 0 && ! code.findAttrId(dictColumn.getAttrId())) {
|
||||
const char* defaultValue = dictColumn.getDefaultValue();
|
||||
ExtType extType(ExtType::Char);
|
||||
ExtSpec extSpec(extType);
|
||||
SQLINTEGER ind = SQL_NTS;
|
||||
ExtField extField(extSpec, (SQLPOINTER)defaultValue, 0, &ind);
|
||||
SqlField& f = code.m_defaultValue->getEntry(++i);
|
||||
f.copyin(ctx, extField);
|
||||
if (! ctx.ok())
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
// create the exec
|
||||
Exec_insert* exec = new Exec_insert(ctl.m_execRoot);
|
||||
ctl.m_execRoot->saveNode(exec);
|
||||
exec->setCode(code);
|
||||
exec->setQuery(execQuery);
|
||||
return exec;
|
||||
}
|
||||
|
||||
void
|
||||
Plan_insert::print(Ctx& ctx)
|
||||
{
|
||||
ctx.print(" [%s", m_insertOp == Insert_op_insert ? "insert" : "write");
|
||||
Plan_base* a[] = { m_table, m_dmlRow, m_exprRow, m_query };
|
||||
printList(ctx, a, 4);
|
||||
ctx.print("]");
|
||||
}
|
||||
|
||||
// Exec_insert
|
||||
|
||||
Exec_insert::Code::~Code()
|
||||
{
|
||||
delete[] m_tableName;
|
||||
delete[] m_attrId;
|
||||
delete[] m_isKey;
|
||||
delete[] m_defaultId;
|
||||
delete m_defaultValue;
|
||||
}
|
||||
|
||||
bool
|
||||
Exec_insert::Code::findAttrId(NdbAttrId attrId) const
|
||||
{
|
||||
for (unsigned i = 1; i <= m_attrCount; i++) {
|
||||
if (m_attrId[i] == attrId)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
Exec_insert::Data::~Data()
|
||||
{
|
||||
}
|
||||
|
||||
Exec_insert::~Exec_insert()
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
Exec_insert::alloc(Ctx& ctx, Ctl& ctl)
|
||||
{
|
||||
// allocate the query
|
||||
ctx_assert(m_query != 0);
|
||||
m_query->alloc(ctx, ctl);
|
||||
// create data
|
||||
Data& data = *new Data();
|
||||
setData(data);
|
||||
}
|
||||
|
||||
void
|
||||
Exec_insert::close(Ctx& ctx)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
Exec_insert::print(Ctx& ctx)
|
||||
{
|
||||
const Code& code = getCode();
|
||||
ctx_assert(m_query != 0);
|
||||
ctx.print(" [insert");
|
||||
ctx.print(" attrId=");
|
||||
for (unsigned i = 1; i <= code.m_attrCount; i++) {
|
||||
if (i > 1)
|
||||
ctx.print(",");
|
||||
ctx.print("%u", (unsigned)code.m_attrId[i]);
|
||||
}
|
||||
ctx.print(" table=%s", code.m_tableName);
|
||||
m_query->print(ctx);
|
||||
ctx.print("]");
|
||||
}
|
@@ -1,229 +0,0 @@
|
||||
/* Copyright (C) 2003 MySQL AB
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||
|
||||
#ifndef ODBC_CODEGEN_Code_insert_hpp
|
||||
#define ODBC_CODEGEN_Code_insert_hpp
|
||||
|
||||
#include <common/common.hpp>
|
||||
#include "Code_base.hpp"
|
||||
#include "Code_dml.hpp"
|
||||
#include "Code_dml_row.hpp"
|
||||
#include "Code_expr_row.hpp"
|
||||
#include "Code_select.hpp"
|
||||
#include "Code_query.hpp"
|
||||
#include "Code_table.hpp"
|
||||
#include "Code_set_row.hpp"
|
||||
|
||||
enum Insert_op {
|
||||
Insert_op_undef = 0,
|
||||
Insert_op_insert = 1,
|
||||
Insert_op_write = 2
|
||||
};
|
||||
|
||||
/**
|
||||
* @class Plan_insert
|
||||
* @brief Insert in PlanTree
|
||||
*
|
||||
* Insert. Becomes directly executable.
|
||||
*/
|
||||
class Plan_insert : public Plan_dml {
|
||||
public:
|
||||
Plan_insert(Plan_root* root, Insert_op insertOp);
|
||||
virtual ~Plan_insert();
|
||||
Plan_base* analyze(Ctx& ctx, Ctl& ctl);
|
||||
void describe(Ctx& ctx);
|
||||
Exec_base* codegen(Ctx& ctx, Ctl& ctl);
|
||||
void print(Ctx& ctx);
|
||||
// children
|
||||
void setTable(Plan_table* table);
|
||||
Plan_dml_row* getDmlRow() const;
|
||||
void setDmlRow(Plan_dml_row* dmlRow);
|
||||
void setExprRow(Plan_expr_row* exprRow);
|
||||
void setSelect(Plan_select* select);
|
||||
void setQuery(Plan_query* query);
|
||||
void setMysqlRow(Plan_set_row* mysqlRow);
|
||||
protected:
|
||||
Insert_op m_insertOp;
|
||||
Plan_table* m_table;
|
||||
Plan_dml_row* m_dmlRow;
|
||||
Plan_expr_row* m_exprRow;
|
||||
Plan_select* m_select;
|
||||
Plan_query* m_query;
|
||||
Plan_set_row* m_mysqlRow;
|
||||
};
|
||||
|
||||
inline
|
||||
Plan_insert::Plan_insert(Plan_root* root, Insert_op insertOp) :
|
||||
Plan_dml(root),
|
||||
m_insertOp(insertOp),
|
||||
m_table(0),
|
||||
m_dmlRow(0),
|
||||
m_exprRow(0),
|
||||
m_select(0),
|
||||
m_query(0),
|
||||
m_mysqlRow(0)
|
||||
{
|
||||
}
|
||||
|
||||
// children
|
||||
|
||||
inline void
|
||||
Plan_insert::setTable(Plan_table* table)
|
||||
{
|
||||
ctx_assert(table != 0);
|
||||
m_table = table;
|
||||
}
|
||||
|
||||
inline void
|
||||
Plan_insert::setDmlRow(Plan_dml_row* dmlRow)
|
||||
{
|
||||
ctx_assert(dmlRow != 0);
|
||||
m_dmlRow = dmlRow;
|
||||
}
|
||||
|
||||
inline Plan_dml_row*
|
||||
Plan_insert::getDmlRow() const
|
||||
{
|
||||
ctx_assert(m_dmlRow != 0);
|
||||
return m_dmlRow;
|
||||
}
|
||||
|
||||
inline void
|
||||
Plan_insert::setExprRow(Plan_expr_row* exprRow)
|
||||
{
|
||||
ctx_assert(exprRow != 0);
|
||||
m_exprRow = exprRow;
|
||||
}
|
||||
|
||||
inline void
|
||||
Plan_insert::setSelect(Plan_select* select)
|
||||
{
|
||||
ctx_assert(select != 0);
|
||||
m_select = select;
|
||||
}
|
||||
|
||||
inline void
|
||||
Plan_insert::setQuery(Plan_query* query)
|
||||
{
|
||||
ctx_assert(query != 0);
|
||||
m_query = query;
|
||||
}
|
||||
|
||||
inline void
|
||||
Plan_insert::setMysqlRow(Plan_set_row* mysqlRow)
|
||||
{
|
||||
ctx_assert(mysqlRow != 0);
|
||||
m_mysqlRow = mysqlRow;
|
||||
}
|
||||
|
||||
/**
|
||||
* @class Exec_insert
|
||||
* @brief Executable insert
|
||||
*/
|
||||
class Exec_insert : public Exec_dml {
|
||||
public:
|
||||
class Code : public Exec_dml::Code {
|
||||
public:
|
||||
Code();
|
||||
virtual ~Code();
|
||||
protected:
|
||||
friend class Plan_insert;
|
||||
friend class Exec_insert;
|
||||
Insert_op m_insertOp;
|
||||
char* m_tableName;
|
||||
unsigned m_attrCount;
|
||||
NdbAttrId* m_attrId;
|
||||
bool* m_isKey;
|
||||
unsigned m_tupleId; // position of tuple id
|
||||
unsigned m_autoIncrement; // position of ai key
|
||||
SqlType m_idType; // type of tuple id or ai key
|
||||
unsigned m_defaultCount;
|
||||
NdbAttrId* m_defaultId;
|
||||
SqlRow* m_defaultValue;
|
||||
bool findAttrId(NdbAttrId attrId) const;
|
||||
};
|
||||
class Data : public Exec_dml::Data {
|
||||
public:
|
||||
Data();
|
||||
virtual ~Data();
|
||||
protected:
|
||||
friend class Exec_insert;
|
||||
};
|
||||
Exec_insert(Exec_root* root);
|
||||
virtual ~Exec_insert();
|
||||
void alloc(Ctx& ctx, Ctl& ctl);
|
||||
void execImpl(Ctx& ctx, Ctl& ctl);
|
||||
void close(Ctx& ctx);
|
||||
void print(Ctx& ctx);
|
||||
// children
|
||||
const Code& getCode() const;
|
||||
Data& getData() const;
|
||||
void setQuery(Exec_query* query);
|
||||
private:
|
||||
Exec_query* m_query;
|
||||
};
|
||||
|
||||
inline
|
||||
Exec_insert::Code::Code() :
|
||||
m_insertOp(Insert_op_undef),
|
||||
m_tableName(0),
|
||||
m_attrCount(0),
|
||||
m_attrId(0),
|
||||
m_isKey(0),
|
||||
m_tupleId(0),
|
||||
m_autoIncrement(0),
|
||||
m_defaultCount(0),
|
||||
m_defaultId(0),
|
||||
m_defaultValue(0)
|
||||
{
|
||||
}
|
||||
|
||||
inline
|
||||
Exec_insert::Data::Data()
|
||||
{
|
||||
}
|
||||
|
||||
inline
|
||||
Exec_insert::Exec_insert(Exec_root* root) :
|
||||
Exec_dml(root),
|
||||
m_query(0)
|
||||
{
|
||||
}
|
||||
|
||||
// children
|
||||
|
||||
inline const Exec_insert::Code&
|
||||
Exec_insert::getCode() const
|
||||
{
|
||||
const Code* code = static_cast<const Code*>(m_code);
|
||||
return *code;
|
||||
}
|
||||
|
||||
inline Exec_insert::Data&
|
||||
Exec_insert::getData() const
|
||||
{
|
||||
Data* data = static_cast<Data*>(m_data);
|
||||
return *data;
|
||||
}
|
||||
|
||||
inline void
|
||||
Exec_insert::setQuery(Exec_query* query)
|
||||
{
|
||||
ctx_assert(m_query == 0 && query != 0);
|
||||
m_query = query;
|
||||
}
|
||||
|
||||
#endif
|
@@ -1,70 +0,0 @@
|
||||
/* Copyright (C) 2003 MySQL AB
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||
|
||||
#include "Code_pred.hpp"
|
||||
#include "Code_pred_op.hpp"
|
||||
#include "Code_root.hpp"
|
||||
|
||||
// Plan_pred
|
||||
|
||||
Plan_pred::~Plan_pred()
|
||||
{
|
||||
}
|
||||
|
||||
bool
|
||||
Plan_pred::isGroupBy(const Plan_expr_row* row) const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
Plan_pred*
|
||||
Plan_pred::opAnd(Plan_pred* pred2)
|
||||
{
|
||||
Plan_pred_op* predAnd = new Plan_pred_op(m_root, Pred_op::And);
|
||||
m_root->saveNode(predAnd);
|
||||
predAnd->setPred(1, this);
|
||||
predAnd->setPred(2, pred2);
|
||||
return predAnd;
|
||||
}
|
||||
|
||||
// Exec_pred
|
||||
|
||||
Exec_pred::Code::~Code()
|
||||
{
|
||||
}
|
||||
|
||||
Exec_pred::Data::~Data()
|
||||
{
|
||||
}
|
||||
|
||||
Exec_pred::~Exec_pred()
|
||||
{
|
||||
}
|
||||
|
||||
Pred_value&
|
||||
Exec_pred::Data::groupValue(unsigned i, bool initFlag)
|
||||
{
|
||||
if (m_groupValue.size() == 0) {
|
||||
m_groupValue.resize(1);
|
||||
}
|
||||
if (initFlag) {
|
||||
//unsigned i2 = m_groupValue.size();
|
||||
//ctx_assert(i == i2);
|
||||
m_groupValue.push_back(Pred_value_unknown);
|
||||
}
|
||||
ctx_assert(i != 0 && i < m_groupValue.size());
|
||||
return m_groupValue[i];
|
||||
}
|
@@ -1,172 +0,0 @@
|
||||
/* Copyright (C) 2003 MySQL AB
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||
|
||||
#ifndef ODBC_CODEGEN_Code_pred_hpp
|
||||
#define ODBC_CODEGEN_Code_pred_hpp
|
||||
|
||||
#include <common/common.hpp>
|
||||
#include <common/DataField.hpp>
|
||||
#include "Code_base.hpp"
|
||||
|
||||
enum Pred_value {
|
||||
Pred_value_unknown = -1,
|
||||
Pred_value_false = 0,
|
||||
Pred_value_true = 1
|
||||
};
|
||||
|
||||
class Ctx;
|
||||
class Plan_expr_row;
|
||||
class Exec_pred;
|
||||
|
||||
/**
|
||||
* @class Plan_pred
|
||||
* @brief Base class for predicates in PlanTree
|
||||
*
|
||||
* Predicate represents a boolean value.
|
||||
*/
|
||||
class Plan_pred : public Plan_base {
|
||||
public:
|
||||
// type is convenient since RTTI cannot be used
|
||||
enum Type {
|
||||
TypeUndefined = 0,
|
||||
TypeComp = 1,
|
||||
TypeOp = 2
|
||||
};
|
||||
Plan_pred(Plan_root* root, Type type);
|
||||
virtual ~Plan_pred() = 0;
|
||||
Type type() const;
|
||||
const TableSet& tableSet() const;
|
||||
const TableSet& noInterp() const;
|
||||
virtual bool isGroupBy(const Plan_expr_row* row) const;
|
||||
// helpers
|
||||
Plan_pred* opAnd(Plan_pred* pred2);
|
||||
protected:
|
||||
const Type m_type;
|
||||
TableSet m_tableSet; // depends on these tables
|
||||
TableSet m_noInterp; // cannot use interpreted TUP program on these tables
|
||||
Exec_pred* m_exec; // probably stupid
|
||||
};
|
||||
|
||||
inline
|
||||
Plan_pred::Plan_pred(Plan_root* root, Type type) :
|
||||
Plan_base(root),
|
||||
m_type(type),
|
||||
m_exec(0)
|
||||
{
|
||||
}
|
||||
|
||||
inline Plan_pred::Type
|
||||
Plan_pred::type() const
|
||||
{
|
||||
return m_type;
|
||||
}
|
||||
|
||||
inline const Plan_pred::TableSet&
|
||||
Plan_pred::tableSet() const
|
||||
{
|
||||
return m_tableSet;
|
||||
}
|
||||
|
||||
inline const Plan_pred::TableSet&
|
||||
Plan_pred::noInterp() const
|
||||
{
|
||||
return m_noInterp;
|
||||
}
|
||||
|
||||
/**
|
||||
* @class Exec_pred
|
||||
* @brief Base class for predicates in ExecTree
|
||||
*/
|
||||
class Exec_pred : public Exec_base {
|
||||
public:
|
||||
class Code : public Exec_base::Code {
|
||||
public:
|
||||
Code();
|
||||
virtual ~Code() = 0;
|
||||
protected:
|
||||
friend class Exec_pred;
|
||||
};
|
||||
class Data : public Exec_base::Data {
|
||||
public:
|
||||
Data();
|
||||
virtual ~Data() = 0;
|
||||
Pred_value getValue() const;
|
||||
Pred_value groupValue(unsigned i) const;
|
||||
protected:
|
||||
friend class Exec_pred;
|
||||
Pred_value m_value; // the value
|
||||
// group-by data
|
||||
typedef std::vector<Pred_value> GroupValue;
|
||||
GroupValue m_groupValue;
|
||||
Pred_value& groupValue(unsigned i, bool initFlag);
|
||||
};
|
||||
Exec_pred(Exec_root* root);
|
||||
virtual ~Exec_pred() = 0;
|
||||
virtual void execInterp(Ctx& ctx, Ctl& ctl) = 0;
|
||||
virtual void evaluate(Ctx& ctx, Ctl& ctl) = 0;
|
||||
// children
|
||||
const Code& getCode() const;
|
||||
Data& getData() const;
|
||||
};
|
||||
|
||||
inline
|
||||
Exec_pred::Code::Code()
|
||||
{
|
||||
}
|
||||
|
||||
inline
|
||||
Exec_pred::Data::Data() :
|
||||
m_value(Pred_value_unknown)
|
||||
{
|
||||
}
|
||||
|
||||
inline Pred_value
|
||||
Exec_pred::Data::getValue() const
|
||||
{
|
||||
return m_value;
|
||||
}
|
||||
|
||||
inline Pred_value
|
||||
Exec_pred::Data::groupValue(unsigned i) const
|
||||
{
|
||||
ctx_assert(i != 0 && i < m_groupValue.size());
|
||||
return m_groupValue[i];
|
||||
}
|
||||
|
||||
inline
|
||||
Exec_pred::Exec_pred(Exec_root* root) :
|
||||
Exec_base(root)
|
||||
{
|
||||
}
|
||||
|
||||
// children
|
||||
|
||||
inline const Exec_pred::Code&
|
||||
Exec_pred::getCode() const
|
||||
{
|
||||
const Code* code = static_cast<const Code*>(m_code);
|
||||
return *code;
|
||||
}
|
||||
|
||||
inline Exec_pred::Data&
|
||||
Exec_pred::getData() const
|
||||
{
|
||||
Data* data = static_cast<Data*>(m_data);
|
||||
return *data;
|
||||
}
|
||||
|
||||
|
||||
#endif
|
@@ -1,188 +0,0 @@
|
||||
/* Copyright (C) 2003 MySQL AB
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||
|
||||
#include "Code_pred.hpp"
|
||||
#include "Code_pred_op.hpp"
|
||||
#include "Code_root.hpp"
|
||||
|
||||
// Pred_op
|
||||
|
||||
const char*
|
||||
Pred_op::name() const
|
||||
{
|
||||
switch (m_opcode) {
|
||||
case And:
|
||||
return "and";
|
||||
case Or:
|
||||
return "or";
|
||||
case Not:
|
||||
return "not";
|
||||
}
|
||||
ctx_assert(false);
|
||||
return "";
|
||||
}
|
||||
|
||||
unsigned
|
||||
Pred_op::arity() const
|
||||
{
|
||||
switch (m_opcode) {
|
||||
case And:
|
||||
case Or:
|
||||
return 2;
|
||||
case Not:
|
||||
return 1;
|
||||
}
|
||||
ctx_assert(false);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Plan_pred_op
|
||||
|
||||
Plan_pred_op::~Plan_pred_op()
|
||||
{
|
||||
}
|
||||
|
||||
Plan_base*
|
||||
Plan_pred_op::analyze(Ctx& ctx, Ctl& ctl)
|
||||
{
|
||||
m_exec = 0;
|
||||
unsigned arity = m_op.arity();
|
||||
// check if we remain in top-level AND-clause
|
||||
const bool topand = ctl.m_topand;
|
||||
if (m_op.m_opcode != Pred_op::And)
|
||||
ctl.m_topand = false;
|
||||
// analyze sub-predicates
|
||||
for (unsigned i = 1; i <= arity; i++) {
|
||||
ctx_assert(m_pred[i] != 0);
|
||||
m_pred[i]->analyze(ctx, ctl);
|
||||
if (! ctx.ok())
|
||||
return 0;
|
||||
}
|
||||
// save top level predicate on list
|
||||
if (topand && ! ctl.m_topand) {
|
||||
ctl.m_topcomp.push_back(this);
|
||||
}
|
||||
ctl.m_topand = topand;
|
||||
// table dependencies are union from operands
|
||||
m_tableSet.clear();
|
||||
for (unsigned i = 1; i <= arity; i++) {
|
||||
const TableSet& ts = m_pred[i]->tableSet();
|
||||
m_tableSet.insert(ts.begin(), ts.end());
|
||||
}
|
||||
// set of tables for which interpreter cannot be used
|
||||
m_noInterp.clear();
|
||||
for (unsigned i = 1; i <= arity; i++) {
|
||||
const TableSet& ts = m_pred[i]->noInterp();
|
||||
m_noInterp.insert(ts.begin(), ts.end());
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
Exec_base*
|
||||
Plan_pred_op::codegen(Ctx& ctx, Ctl& ctl)
|
||||
{
|
||||
if (m_exec != 0)
|
||||
return m_exec;
|
||||
unsigned arity = m_op.arity();
|
||||
Exec_pred_op* exec = new Exec_pred_op(ctl.m_execRoot);
|
||||
ctl.m_execRoot->saveNode(exec);
|
||||
// create code for operands
|
||||
for (unsigned i = 1; i <= arity; i++) {
|
||||
ctx_assert(m_pred[i] != 0);
|
||||
Exec_pred* execPred = static_cast<Exec_pred*>(m_pred[i]->codegen(ctx, ctl));
|
||||
if (! ctx.ok())
|
||||
return 0;
|
||||
ctx_assert(execPred != 0);
|
||||
exec->setPred(i, execPred);
|
||||
}
|
||||
// create the code
|
||||
Exec_pred_op::Code& code = *new Exec_pred_op::Code(m_op);
|
||||
exec->setCode(code);
|
||||
m_exec = exec;
|
||||
return exec;
|
||||
}
|
||||
|
||||
void
|
||||
Plan_pred_op::print(Ctx& ctx)
|
||||
{
|
||||
ctx.print(" [%s", m_op.name());
|
||||
Plan_base* a[] = { m_pred[1], m_pred[2] };
|
||||
printList(ctx, a, m_op.arity());
|
||||
ctx.print("]");
|
||||
}
|
||||
|
||||
bool
|
||||
Plan_pred_op::isGroupBy(const Plan_expr_row* row) const
|
||||
{
|
||||
const unsigned arity = m_op.arity();
|
||||
for (unsigned i = 1; i <= arity; i++) {
|
||||
ctx_assert(m_pred[i] != 0);
|
||||
if (! m_pred[i]->isGroupBy(row))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// Code_pred_op
|
||||
|
||||
Exec_pred_op::Code::~Code()
|
||||
{
|
||||
}
|
||||
|
||||
Exec_pred_op::Data::~Data()
|
||||
{
|
||||
}
|
||||
|
||||
Exec_pred_op::~Exec_pred_op()
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
Exec_pred_op::alloc(Ctx& ctx, Ctl& ctl)
|
||||
{
|
||||
const Code& code = getCode();
|
||||
// allocate sub-predicates
|
||||
unsigned arity = code.m_op.arity();
|
||||
for (unsigned i = 1; i <= arity; i++) {
|
||||
ctx_assert(m_pred[i] != 0);
|
||||
m_pred[i]->alloc(ctx, ctl);
|
||||
if (! ctx.ok())
|
||||
return;
|
||||
}
|
||||
Data& data = *new Data;
|
||||
setData(data);
|
||||
}
|
||||
|
||||
void
|
||||
Exec_pred_op::close(Ctx& ctx)
|
||||
{
|
||||
const Code& code = getCode();
|
||||
unsigned arity = code.m_op.arity();
|
||||
for (unsigned i = 1; i <= arity; i++) {
|
||||
ctx_assert(m_pred[i] != 0);
|
||||
m_pred[i]->close(ctx);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Exec_pred_op::print(Ctx& ctx)
|
||||
{
|
||||
const Code& code = getCode();
|
||||
ctx.print(" [%s", code.m_op.name());
|
||||
Exec_base* a[] = { m_pred[1], m_pred[2] };
|
||||
printList(ctx, a, code.m_op.arity());
|
||||
ctx.print("]");
|
||||
}
|
@@ -1,158 +0,0 @@
|
||||
/* Copyright (C) 2003 MySQL AB
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||
|
||||
#ifndef ODBC_CODEGEN_Code_pred_op_hpp
|
||||
#define ODBC_CODEGEN_Code_pred_op_hpp
|
||||
|
||||
#include <common/common.hpp>
|
||||
#include <common/DataField.hpp>
|
||||
#include "Code_pred.hpp"
|
||||
|
||||
/**
|
||||
* @class Pred_op
|
||||
* @brief Boolean operators
|
||||
*/
|
||||
struct Pred_op {
|
||||
enum Opcode {
|
||||
And = 1, // binary
|
||||
Or,
|
||||
Not // unary
|
||||
};
|
||||
Pred_op(Opcode opcode);
|
||||
const char* name() const;
|
||||
unsigned arity() const;
|
||||
Opcode m_opcode;
|
||||
};
|
||||
|
||||
inline
|
||||
Pred_op::Pred_op(Opcode opcode) :
|
||||
m_opcode(opcode)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @class Plan_pred_op
|
||||
* @brief Operator node in a predicate in PlanTree
|
||||
*/
|
||||
class Plan_pred_op : public Plan_pred {
|
||||
public:
|
||||
Plan_pred_op(Plan_root* root, Pred_op op);
|
||||
virtual ~Plan_pred_op();
|
||||
Plan_base* analyze(Ctx& ctx, Ctl& ctl);
|
||||
Exec_base* codegen(Ctx& ctx, Ctl& ctl);
|
||||
void print(Ctx& ctx);
|
||||
bool isGroupBy(const Plan_expr_row* row) const;
|
||||
// children
|
||||
void setPred(unsigned i, Plan_pred* pred);
|
||||
protected:
|
||||
friend class Plan_pred;
|
||||
Pred_op m_op;
|
||||
Plan_pred* m_pred[1 + 2];
|
||||
};
|
||||
|
||||
inline
|
||||
Plan_pred_op::Plan_pred_op(Plan_root* root, Pred_op op) :
|
||||
Plan_pred(root, TypeOp),
|
||||
m_op(op)
|
||||
{
|
||||
m_pred[0] = m_pred[1] = m_pred[2] = 0;
|
||||
}
|
||||
|
||||
inline void
|
||||
Plan_pred_op::setPred(unsigned i, Plan_pred* pred)
|
||||
{
|
||||
ctx_assert(1 <= i && i <= m_op.arity() && pred != 0);
|
||||
m_pred[i] = pred;
|
||||
}
|
||||
|
||||
/**
|
||||
* @class Exec_pred_op
|
||||
* @brief Operator node in a predicate in ExecTree
|
||||
*/
|
||||
class Exec_pred_op : public Exec_pred {
|
||||
public:
|
||||
class Code : public Exec_pred::Code {
|
||||
public:
|
||||
Code(Pred_op op);
|
||||
virtual ~Code();
|
||||
protected:
|
||||
friend class Exec_pred_op;
|
||||
Pred_op m_op;
|
||||
};
|
||||
class Data : public Exec_pred::Data {
|
||||
public:
|
||||
Data();
|
||||
virtual ~Data();
|
||||
protected:
|
||||
friend class Exec_pred_op;
|
||||
};
|
||||
Exec_pred_op(Exec_root* root);
|
||||
virtual ~Exec_pred_op();
|
||||
void alloc(Ctx& ctx, Ctl& ctl);
|
||||
void execInterp(Ctx& ctx, Ctl& ctl);
|
||||
void evaluate(Ctx& ctx, Ctl& ctl);
|
||||
void close(Ctx& ctx);
|
||||
void print(Ctx& ctx);
|
||||
// children
|
||||
const Code& getCode() const;
|
||||
Data& getData() const;
|
||||
void setPred(unsigned i, Exec_pred* pred);
|
||||
protected:
|
||||
Exec_pred* m_pred[1 + 2];
|
||||
};
|
||||
|
||||
inline
|
||||
Exec_pred_op::Code::Code(Pred_op op) :
|
||||
m_op(op)
|
||||
{
|
||||
}
|
||||
|
||||
inline
|
||||
Exec_pred_op::Data::Data()
|
||||
{
|
||||
}
|
||||
|
||||
inline
|
||||
Exec_pred_op::Exec_pred_op(Exec_root* root) :
|
||||
Exec_pred(root)
|
||||
{
|
||||
m_pred[0] = m_pred[1] = m_pred[2] = 0;
|
||||
}
|
||||
|
||||
// children
|
||||
|
||||
inline const Exec_pred_op::Code&
|
||||
Exec_pred_op::getCode() const
|
||||
{
|
||||
const Code* code = static_cast<const Code*>(m_code);
|
||||
return *code;
|
||||
}
|
||||
|
||||
inline Exec_pred_op::Data&
|
||||
Exec_pred_op::getData() const
|
||||
{
|
||||
Data* data = static_cast<Data*>(m_data);
|
||||
return *data;
|
||||
}
|
||||
|
||||
inline void
|
||||
Exec_pred_op::setPred(unsigned i, Exec_pred* pred)
|
||||
{
|
||||
ctx_assert(1 <= i && i <= 2 && m_pred[i] == 0);
|
||||
m_pred[i] = pred;
|
||||
}
|
||||
|
||||
#endif
|
@@ -1,299 +0,0 @@
|
||||
/* Copyright (C) 2003 MySQL AB
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||
|
||||
#include <common/StmtArea.hpp>
|
||||
#include "Code_query.hpp"
|
||||
#include "Code_query_project.hpp"
|
||||
#include "Code_query_count.hpp"
|
||||
|
||||
// Plan_query
|
||||
|
||||
Plan_query::~Plan_query()
|
||||
{
|
||||
}
|
||||
|
||||
Plan_expr_row*
|
||||
Plan_query::getRow()
|
||||
{
|
||||
ctx_assert(false);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
Plan_query::describe(Ctx& ctx)
|
||||
{
|
||||
const Plan_expr_row* exprRow = getRow();
|
||||
const unsigned count = exprRow->getSize();
|
||||
// create IRD
|
||||
DescArea& ird = descArea(Desc_usage_IRD);
|
||||
ird.setCount(ctx, count);
|
||||
for (unsigned i = 1; i <= count; i++) {
|
||||
DescRec& rec = ird.getRecord(i);
|
||||
const Plan_expr* expr = exprRow->m_exprList[i];
|
||||
const SqlType& sqlType = expr->sqlType();
|
||||
// data type
|
||||
SQLSMALLINT desc_TYPE = sqlType.type();
|
||||
rec.setField(SQL_DESC_TYPE, desc_TYPE);
|
||||
SQLSMALLINT desc_CONCISE_TYPE = desc_TYPE;
|
||||
rec.setField(SQL_DESC_CONCISE_TYPE, desc_CONCISE_TYPE);
|
||||
SQLSMALLINT desc_DESC_DATETIME_INTERVAL_CODE = 0;
|
||||
rec.setField(SQL_DESC_DATETIME_INTERVAL_CODE, desc_DESC_DATETIME_INTERVAL_CODE);
|
||||
// nullable
|
||||
SQLSMALLINT desc_NULLABLE = sqlType.nullable() ? SQL_NULLABLE : SQL_NO_NULLS;
|
||||
rec.setField(SQL_DESC_NULLABLE, desc_NULLABLE);
|
||||
// unsigned
|
||||
SQLSMALLINT desc_UNSIGNED;
|
||||
switch (sqlType.type()) {
|
||||
case SQL_SMALLINT:
|
||||
case SQL_INTEGER:
|
||||
case SQL_BIGINT:
|
||||
desc_UNSIGNED = sqlType.unSigned() ? SQL_TRUE : SQL_FALSE;
|
||||
break;
|
||||
default:
|
||||
desc_UNSIGNED = SQL_TRUE; // thus spake microsoft
|
||||
break;
|
||||
}
|
||||
rec.setField(SQL_DESC_UNSIGNED, desc_UNSIGNED);
|
||||
// sizes
|
||||
SQLUINTEGER desc_LENGTH = sqlType.length();
|
||||
rec.setField(SQL_DESC_LENGTH, desc_LENGTH);
|
||||
SQLINTEGER desc_OCTET_LENGTH = sqlType.size();
|
||||
rec.setField(SQL_DESC_OCTET_LENGTH, desc_OCTET_LENGTH);
|
||||
SQLINTEGER desc_DISPLAY_SIZE = sqlType.displaySize();
|
||||
rec.setField(SQL_DESC_DISPLAY_SIZE, desc_DISPLAY_SIZE);
|
||||
// name
|
||||
ctx_assert(i < exprRow->m_aliasList.size());
|
||||
const char* desc_NAME = exprRow->m_aliasList[i].c_str();
|
||||
rec.setField(SQL_DESC_NAME, desc_NAME);
|
||||
}
|
||||
ctx_log3(("describe %u columns done", count));
|
||||
stmtArea().setFunction(ctx, "SELECT CURSOR", SQL_DIAG_SELECT_CURSOR);
|
||||
}
|
||||
|
||||
// Exec_query
|
||||
|
||||
Exec_query::Code::~Code()
|
||||
{
|
||||
}
|
||||
|
||||
Exec_query::Data::~Data()
|
||||
{
|
||||
delete m_extRow;
|
||||
m_extRow = 0;
|
||||
delete[] m_extPos;
|
||||
m_extPos = 0;
|
||||
}
|
||||
|
||||
Exec_query::~Exec_query()
|
||||
{
|
||||
}
|
||||
|
||||
const Exec_query*
|
||||
Exec_query::getRawQuery() const
|
||||
{
|
||||
ctx_assert(false);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
Exec_query::bind(Ctx& ctx)
|
||||
{
|
||||
const Code& code = getCode();
|
||||
const SqlSpecs& sqlSpecs = code.sqlSpecs();
|
||||
const unsigned count = sqlSpecs.count();
|
||||
// read ARD
|
||||
DescArea& ard = descArea(Desc_usage_ARD);
|
||||
const unsigned ardCount = ard.getCount();
|
||||
// create specification row
|
||||
ExtSpecs extSpecs(count);
|
||||
for (unsigned i = 1; i <= count; i++) {
|
||||
ExtType extType;
|
||||
if (i <= ardCount) {
|
||||
OdbcData descData;
|
||||
DescRec& rec = ard.getRecord(i);
|
||||
// check for unbound column
|
||||
rec.getField(ctx, SQL_DESC_DATA_PTR, descData);
|
||||
SQLPOINTER desc_DATA_PTR = descData.type() != OdbcData::Undef ? descData.pointer() : 0;
|
||||
if (desc_DATA_PTR == 0) {
|
||||
extType.setType(ctx, ExtType::Unbound);
|
||||
} else {
|
||||
rec.getField(ctx, SQL_DESC_TYPE, descData);
|
||||
if (descData.type() == OdbcData::Undef) {
|
||||
ctx.pushStatus(Error::Gen, "query column %u: external type not defined", i);
|
||||
return;
|
||||
}
|
||||
SQLSMALLINT desc_TYPE = descData.smallint();
|
||||
if (desc_TYPE == SQL_C_DEFAULT) {
|
||||
if (i <= code.m_sqlSpecs.count())
|
||||
desc_TYPE = code.m_sqlSpecs.getEntry(i).sqlType().sqlcdefault(ctx);
|
||||
}
|
||||
switch (desc_TYPE) {
|
||||
case SQL_C_CHAR:
|
||||
case SQL_C_BINARY:
|
||||
case SQL_C_SHORT: // for sun.jdbc.odbc
|
||||
case SQL_C_SSHORT:
|
||||
case SQL_C_USHORT:
|
||||
case SQL_C_LONG: // for sun.jdbc.odbc
|
||||
case SQL_C_SLONG:
|
||||
case SQL_C_ULONG:
|
||||
case SQL_C_SBIGINT:
|
||||
case SQL_C_UBIGINT:
|
||||
case SQL_C_FLOAT:
|
||||
case SQL_C_DOUBLE:
|
||||
case SQL_C_TYPE_TIMESTAMP:
|
||||
break;
|
||||
default:
|
||||
ctx.pushStatus(Error::Gen, "query column %u: unsupported external type %d", i, (int)desc_TYPE);
|
||||
return;
|
||||
}
|
||||
extType.setType(ctx, static_cast<ExtType::Type>(desc_TYPE));
|
||||
}
|
||||
} else {
|
||||
extType.setType(ctx, ExtType::Unbound);
|
||||
}
|
||||
const ExtSpec extSpec(extType);
|
||||
extSpecs.setEntry(i, extSpec);
|
||||
}
|
||||
// create data row
|
||||
ExtRow& extRow = *new ExtRow(extSpecs);
|
||||
unsigned boundCount = 0;
|
||||
for (unsigned i = 1; i <= count; i++) {
|
||||
const ExtSpec& extSpec = extSpecs.getEntry(i);
|
||||
if (extSpec.extType().type() != ExtType::Unbound) {
|
||||
OdbcData descData;
|
||||
DescRec& rec = ard.getRecord(i);
|
||||
rec.getField(ctx, SQL_DESC_DATA_PTR, descData);
|
||||
SQLPOINTER desc_DATA_PTR = descData.type() != OdbcData::Undef ? descData.pointer() : 0;
|
||||
rec.getField(ctx, SQL_DESC_OCTET_LENGTH, descData);
|
||||
SQLINTEGER desc_OCTET_LENGTH = descData.type() != OdbcData::Undef ? descData.integer() : 0;
|
||||
rec.getField(ctx, SQL_DESC_INDICATOR_PTR, descData);
|
||||
SQLINTEGER* desc_INDICATOR_PTR = descData.type() != OdbcData::Undef ? descData.integerPtr() : 0;
|
||||
ctx_log4(("column %u: bind to 0x%x %d 0x%x", i, (unsigned)desc_DATA_PTR, (int)desc_OCTET_LENGTH, (unsigned)desc_INDICATOR_PTR));
|
||||
ExtField extField(extSpec, desc_DATA_PTR, desc_OCTET_LENGTH, desc_INDICATOR_PTR, i);
|
||||
extRow.setEntry(i, extField);
|
||||
boundCount++;
|
||||
} else {
|
||||
ExtField extField(extSpec, i);
|
||||
extRow.setEntry(i, extField);
|
||||
}
|
||||
}
|
||||
Data& data = getData();
|
||||
delete data.m_extRow;
|
||||
data.m_extRow = &extRow;
|
||||
ctx_log3(("bound %u out of %u columns", boundCount, count));
|
||||
}
|
||||
|
||||
// execute and fetch
|
||||
|
||||
void
|
||||
Exec_query::execute(Ctx& ctx, Ctl& ctl)
|
||||
{
|
||||
Data& data = getData();
|
||||
execImpl(ctx, ctl);
|
||||
if (! ctx.ok())
|
||||
return;
|
||||
data.initState();
|
||||
if (m_topLevel) {
|
||||
stmtArea().setRowCount(ctx, data.getCount());
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
Exec_query::fetch(Ctx& ctx, Ctl& ctl)
|
||||
{
|
||||
const Code& code = getCode();
|
||||
Data& data = getData();
|
||||
if (data.fetch(ctx, ctl)) {
|
||||
if (m_topLevel) {
|
||||
stmtArea().setRowCount(ctx, data.getCount());
|
||||
}
|
||||
if (data.m_extRow != 0) {
|
||||
data.sqlRow().copyout(ctx, *data.m_extRow);
|
||||
if (! ctx.ok())
|
||||
return false;
|
||||
}
|
||||
if (data.m_extPos != 0) {
|
||||
const unsigned count = code.sqlSpecs().count();
|
||||
for (unsigned i = 0; i <= count; i++) {
|
||||
data.m_extPos[i] = 0;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
if (m_topLevel) {
|
||||
stmtArea().setRowCount(ctx, data.getCount());
|
||||
if (ctx.ok()) {
|
||||
ctx.setCode(SQL_NO_DATA);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// odbc support
|
||||
|
||||
void
|
||||
Exec_query::sqlGetData(Ctx& ctx, SQLUSMALLINT columnNumber, SQLSMALLINT targetType, SQLPOINTER targetValue, SQLINTEGER bufferLength, SQLINTEGER* strlen_or_Ind)
|
||||
{
|
||||
const Code& code = getCode();
|
||||
Data& data = getData();
|
||||
const SqlSpecs& sqlSpecs = code.m_sqlSpecs;
|
||||
const unsigned count = sqlSpecs.count();
|
||||
if (columnNumber == 0 || columnNumber > count) {
|
||||
ctx.pushStatus(Sqlstate::_07009, Error::Gen, "column index %u is not within 1 to %u", (unsigned)columnNumber, count);
|
||||
return;
|
||||
}
|
||||
// create positions array on first use
|
||||
if (data.m_extPos == 0) {
|
||||
data.m_extPos = new int[1 + count];
|
||||
for (unsigned i = 0; i <= count; i++) {
|
||||
data.m_extPos[i] = 0;
|
||||
}
|
||||
}
|
||||
if (targetType == SQL_ARD_TYPE) {
|
||||
// get type from ARD
|
||||
DescArea& ard = descArea(Desc_usage_ARD);
|
||||
const unsigned ardCount = ard.getCount();
|
||||
if (columnNumber <= ardCount) {
|
||||
OdbcData descData;
|
||||
DescRec& rec = ard.getRecord(columnNumber);
|
||||
rec.getField(ctx, SQL_DESC_CONCISE_TYPE, descData);
|
||||
if (descData.type() != OdbcData::Undef) {
|
||||
targetType = descData.smallint();
|
||||
}
|
||||
}
|
||||
if (targetType == SQL_ARD_TYPE) {
|
||||
ctx.pushStatus(Sqlstate::_07009, Error::Gen, "output column %u type not bound - cannot use SQL_ARD_TYPE", (unsigned)columnNumber);
|
||||
return;
|
||||
}
|
||||
}
|
||||
ExtType extType;
|
||||
if (targetValue != 0) {
|
||||
extType.setType(ctx, static_cast<ExtType::Type>(targetType));
|
||||
// check if supported
|
||||
if (! ctx.ok())
|
||||
return;
|
||||
} else {
|
||||
extType.setType(ctx, ExtType::Unbound);
|
||||
}
|
||||
ExtSpec extSpec(extType);
|
||||
ExtField extField(extSpec, targetValue, bufferLength, strlen_or_Ind, columnNumber);
|
||||
// copy out and update position
|
||||
extField.setPos(data.m_extPos[columnNumber]);
|
||||
const SqlRow& sqlRow = data.sqlRow();
|
||||
const SqlField& sqlField = sqlRow.getEntry(columnNumber);
|
||||
sqlField.copyout(ctx, extField);
|
||||
data.m_extPos[columnNumber] = extField.getPos();
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user