Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Dolt panic on index errors #2991

Closed
CaptainStabs opened this issue Mar 15, 2022 · 6 comments
Closed

Dolt panic on index errors #2991

CaptainStabs opened this issue Mar 15, 2022 · 6 comments
Labels
bug Something isn't working

Comments

@CaptainStabs
Copy link

CaptainStabs commented Mar 15, 2022

>dolt sql -q "delete from prices where cms_certification_num in ('210027', '393302', '330239', '390002', '390016', '390028', '390039', '390045', '390058', '390063', '390067', '390068', '390073', '390091', '390101', '390102', '390104', '390107', '390114', '390117', '390164', '390178', '390233', '390328', '391301', '391313', '391316', '390071');"
panic: runtime error: index out of range [0] with length 0

goroutine 1 [running]:
github.com/dolthub/dolt/go/libraries/doltcore/sqle/sqlutil.DoltKeyAndMappingFromSqlRow({0x277dc08, 0xc00046f2c0}, {0x277dab8, 0xc000198280}, {0x0, 0x0, 0x1bf24b6}, {0x279faa0, 0xc000162780})
        /src/libraries/doltcore/sqle/sqlutil/sql_row.go:199 +0x8e7
github.com/dolthub/dolt/go/libraries/doltcore/sqle/writer.(*nomsTableWriter).Delete(0xc00053aa00, 0xc00046f2c0, {0x0, 0x0, 0x0})
        /src/libraries/doltcore/sqle/writer/noms_table_writer.go:112 +0x226
github.com/dolthub/go-mysql-server/sql/plan.(*deleteIter).Next(0xc0031b2100, 0x100c00011f900)
        /go/pkg/mod/github.com/dolthub/go-mysql-server@v0.11.1-0.20220311194643-f7ae1605f60b/sql/plan/delete.go:139 +0xa9
github.com/dolthub/go-mysql-server/sql/plan.(*tableEditorIter).Next(0xc0031b2140, 0xc00046f2c0)
        /go/pkg/mod/github.com/dolthub/go-mysql-server@v0.11.1-0.20220311194643-f7ae1605f60b/sql/plan/table_editor.go:51 +0x78
github.com/dolthub/go-mysql-server/sql/plan.(*accumulatorIter).Next(0xc0005365a0, 0xc00046f2c0)
        /go/pkg/mod/github.com/dolthub/go-mysql-server@v0.11.1-0.20220311194643-f7ae1605f60b/sql/plan/row_update_accumulator.go:309 +0x1f9
github.com/dolthub/go-mysql-server/sql/plan.(*trackedRowIter).Next(0xc0009c7ea0, 0x0)
        /go/pkg/mod/github.com/dolthub/go-mysql-server@v0.11.1-0.20220311194643-f7ae1605f60b/sql/plan/process.go:372 +0x2e
github.com/dolthub/go-mysql-server.transactionCommittingIter.Next(...)
        /go/pkg/mod/github.com/dolthub/go-mysql-server@v0.11.1-0.20220311194643-f7ae1605f60b/engine.go:397
github.com/dolthub/dolt/go/cmd/dolt/commands/engine.printOKResult(0x3654e48, {0x275fb80, 0xc000536600})
        /src/cmd/dolt/commands/engine/sql_print.go:87 +0x42
github.com/dolthub/dolt/go/cmd/dolt/commands/engine.PrettyPrintResults(0xc00046f2c0, 0x0, {0x3654e48, 0x1, 0x1}, {0x275fb80, 0xc000536600}, 0x20)
        /src/cmd/dolt/commands/engine/sql_print.go:61 +0x2d9
github.com/dolthub/dolt/go/cmd/dolt/commands.runMultiStatementMode(0x277d310, 0xc0005f4720, {0x274a340, 0xc0009d6500}, 0x0)
        /src/cmd/dolt/commands/sql.go:662 +0x4c8
github.com/dolthub/dolt/go/cmd/dolt/commands.execMultiStatements({0x277d310, 0xc000642b40}, 0x64, 0x8, {0x274a340, 0xc0009d6500}, 0x1, {0xc0007ec330, 0xc0005076f8})
        /src/cmd/dolt/commands/sql.go:444 +0x14a
github.com/dolthub/dolt/go/cmd/dolt/commands.queryMode({0x277d310, 0xc000642b40}, 0x240ac8f, 0x4b8, 0xc0005cfc20, {0xc00014c160, 0x7}, {0xc0007ec330, 0x1e}, 0x0, ...)
        /src/cmd/dolt/commands/sql.go:341 +0x25c
github.com/dolthub/dolt/go/cmd/dolt/commands.SqlCmd.Exec({{0x240ac8f, 0xc000507900}}, {0x277d310, 0xc000642b40}, {0xc00048ce38, 0x8}, {0xc00014e020, 0x2, 0x2}, 0xc000246c60)
        /src/cmd/dolt/commands/sql.go:202 +0x819
github.com/dolthub/dolt/go/cmd/dolt/cli.SubCommandHandler.handleCommand({{0x2408d84, 0x4}, {0x24224c5, 0x11}, {0x0, 0x0}, {0xc00016e840, 0x2b, 0x2b}, 0x0}, ...)
        /src/cmd/dolt/cli/command.go:222 +0x282
github.com/dolthub/dolt/go/cmd/dolt/cli.SubCommandHandler.Exec({{0x2408d84, 0x4}, {0x24224c5, 0x11}, {0x0, 0x0}, {0xc00016e840, 0x2b, 0x2b}, 0x0}, ...)
        /src/cmd/dolt/cli/command.go:179 +0x47f
main.runMain()
        /src/cmd/dolt/dolt.go:345 +0x6e5
main.main()
        /src/cmd/dolt/dolt.go:131 +0x19

Same panic with and cms_certification_num != NULL;, but no panic with and cms_certification_num IS NOT NULL;

@max-hoffman

@max-hoffman
Copy link
Contributor

max-hoffman commented Mar 15, 2022

@CaptainStabs can you manage with the null workaround for one week, until a new release around Monday or so?

@fulghum fulghum added the bug Something isn't working label Mar 15, 2022
@max-hoffman
Copy link
Contributor

max-hoffman commented Mar 16, 2022

More observations:

  1. We cannot checkout a table after dropping the foreign key on cms_certification_num:
hospital_price_transparency_v3> alter table prices drop foreign key g9j30676;
$ dolt checkout prices
$ dolt status 
	modified:       prices
diff --dolt a/prices b/prices
--- a/prices @ i538628tumgj030d4if80n0knri4e2lk
+++ b/prices @ i538628tumgj030d4if80n0knri4e2lk
 CREATE TABLE `prices` (
   `cms_certification_num` char(6) NOT NULL,
   `payer` varchar(256) NOT NULL,
   `code` varchar(128) NOT NULL DEFAULT "NONE",
   `internal_revenue_code` varchar(128) NOT NULL DEFAULT "NONE",
   `units` varchar(128),
   `description` varchar(2048),
   `inpatient_outpatient` enum('inpatient','outpatient','both','unspecified') NOT NULL DEFAULT "UNSPECIFIED",
   `price` decimal(10,2) NOT NULL,
   `code_disambiguator` varchar(2048) NOT NULL DEFAULT "NONE",
   PRIMARY KEY (`cms_certification_num`,`code`,`inpatient_outpatient`,`internal_revenue_code`,`code_disambiguator`,`payer`),
-  KEY `cms_certification_num` (`cms_certification_num`),
-  CONSTRAINT `g9j30676` FOREIGN KEY (`cms_certification_num`) REFERENCES `hospitals` (`cms_certification_num`)
+  KEY `cms_certification_num` (`cms_certification_num`)
 ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
+-----+-----------------------+-------+------+-----------------------+-------+-------------+----------------------+-------+--------------------+
|     | cms_certification_num | payer | code | internal_revenue_code | units | description | inpatient_outpatient | price | code_disambiguator |
+-----+-----------------------+-------+------+-----------------------+-------+-------------+----------------------+-------+--------------------+
+-----+-----------------------+-------+------+-----------------------+-------+-------------+----------------------+-------+--------------------+

Checking out everything still works:

$ dolt checkout .
$ dolt status
On branch main
nothing to commit, working tree clean
  1. The panic happens when we try to delete the rows twice. The error source is the index iterator and can be reproduced in a select:
hospital_price_transparency_v3> select * from prices where cms_certification_num = '210027' limit 1;
+-----------------------+--------------+-------+-----------------------+-------+--------------------------------+----------------------+-------+--------------------+
| cms_certification_num | payer        | code  | internal_revenue_code | units | description                    | inpatient_outpatient | price | code_disambiguator |
+-----------------------+--------------+-------+-----------------------+-------+--------------------------------+----------------------+-------+--------------------+
| 210027                | GROSS CHARGE | 10010 | NONE                  | NULL  | FNA BX W/CT GUID EACH ADD LESN | UNSPECIFIED          | 1.00  | 3066               |
+-----------------------+--------------+-------+-----------------------+-------+--------------------------------+----------------------+-------+--------------------+
hospital_price_transparency_v3> delete from prices where cms_certification_num = '210027';
Query OK, 12585 rows affected
hospital_price_transparency_v3> select * from prices where cms_certification_num = '210027';
unable to find field with index 0 in row of 0 columns

Removing the index fixes this error (removing the index requires removing the FK)

hospital_price_transparency_v3> alter table prices drop index cms_certification_num;
hospital_price_transparency_v3> alter table prices drop foreign key g9j30676;
hospital_price_transparency_v3> select * from prices where cms_certification_num = '210027';
+-----------------------+-------+------+-----------------------+-------+-------------+----------------------+-------+--------------------+
| cms_certification_num | payer | code | internal_revenue_code | units | description | inpatient_outpatient | price | code_disambiguator |
+-----------------------+-------+------+-----------------------+-------+-------------+----------------------+-------+--------------------+
+-----------------------+-------+------+-----------------------+-------+-------------+----------------------+-------+--------------------+
hospital_price_transparency_v3> delete from prices where cms_certification_num = '210027';
Query OK, 0 rows affected

@zachmu
Copy link
Member

zachmu commented Mar 16, 2022

@Hydrocharged @andrew-wm-arthur

Looks like this is a case where index iteration is subtly buggy. Can you take a look?

@max-hoffman
Copy link
Contributor

A couple more clarifications:

  • the panic is downstream of the nil row error unable to find field with index 0 in row of 0 columns. If i fix the panic, i still get this error.

  • I think the nil row comes from indexLookupRowIterAdapter.queueRows adding the lookupResult finalizer lookupResult{idx: idx,r: nil,err: ctx.Err()} after the context is closed.

  • the error occurs when the nil row reaches a Project operator eval.

It seems like whatever is closing the context should be setting the context error as io.EOF? I haven't been able to repro the error on a fresh database. There's something about the secondary index/foreign key/dolt version of that table contributing to the error that I'm missing.

@max-hoffman
Copy link
Contributor

@CaptainStabs This PR fixes the root source of the bug #3013, but it does not correct the bounty database that still has an index incompatible with clustered index.

In order to fix the secondary index, @alecstein or another bounty participant would have to delete and rebuild the cms_certification_num index and its foreign key relationship with the next dolt release.

In the meantime, the panic should be fixed, and you can get normal results by sidestepping the secondary index by specifying a filter on the code table, which will force a lookup through the primary key:

hospital_price_transparency_v3> select * from prices where cms_certification_num = '210027' and code is not null limit 1;
+-----------------------+-------+------+-----------------------+-------+-------------+----------------------+-------+--------------------+
| cms_certification_num | payer | code | internal_revenue_code | units | description | inpatient_outpatient | price | code_disambiguator |
+-----------------------+-------+------+-----------------------+-------+-------------+----------------------+-------+--------------------+
+-----------------------+-------+------+-----------------------+-------+-------------+----------------------+-------+--------------------+

Until the index is rebuilt, you might see errors like this indicating we've hit a bad index value:

hospital_price_transparency_v3> delete from prices where cms_certification_num = '210027';
unexpected nil row
hospital_price_transparency_v3> select * from prices where cms_certification_num = '210027' limit 1;
unable to find field with index 0 in row of 0 columns

The select/delete has to return zero results before you'll see these errors.

@CaptainStabs
Copy link
Author

@CaptainStabs can you manage with the null workaround for one week, until a new release around Monday or so?

Yeah, it wasn't a big issue!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

4 participants